home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / graphics / pstricks / src / pstricks.doc (.txt) < prev    next >
LaTeX Document  |  1993-04-07  |  134KB  |  4,315 lines

  1. %% BEGIN pstricks.doc
  2. \def\fileversion{0.93a}
  3. \def\filedate{93/03/12}
  4. % File `pstricks.doc': PostScript macros for Generic TeX.
  5. %% See the PSTricks read-me file and the User's Guide for documentation.
  6. %% COPYRIGHT 1993, by Timothy Van Zandt, tvz@Princeton.EDU
  7. %% Copying of part or all of any file in the pstricks.tex package
  8. %% is allowed under the following conditions only:
  9. %% (1) You may freely distribute unchanged copies of the files. Please
  10. %%     include the documentation when you do so.
  11. %% (2) You may modify a renamed copy of any file, but only for personal
  12. %%     use or use within an organization.
  13. %% (3) You may copy fragments from the files, for personal use or for use
  14. %%     in a macro package for distribution, as long as credit is given
  15. %%     where credit is due.
  16. %% You are NOT ALLOWED to take money for the distribution or use of
  17. %% these files or modified versions or fragments thereof, except for
  18. %% a nominal charge for copying etc.
  19. % **************************************************************************
  20. % This is `pstricks.doc', which contains the documented code for the PSTricks
  21. % package. See the PSTricks read-me file for information on how to
  22. % use this file.
  23. % **************************************************************************
  24. % \EndDocPreamble
  25. % \CheckSum{5048}
  26. % \CharacterTable
  27. %  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
  28. %   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
  29. %   Digits        \0\1\2\3\4\5\6\7\8\9
  30. %   Exclamation   \!     Double quote  \"     Hash (number) \#
  31. %   Dollar        \$     Percent       \%     Ampersand     \&
  32. %   Acute accent  \'     Left paren    \(     Right paren   \)
  33. %   Asterisk      \*     Plus          \+     Comma         \,
  34. %   Minus         \-     Point         \.     Solidus       \/
  35. %   Colon         \:     Semicolon     \;     Less than     \<
  36. %   Equals        \=     Greater than  \>     Question mark \?
  37. %   Commercial at \@     Left bracket  \[     Backslash     \\
  38. %   Right bracket \]     Circumflex    \^     Underscore    \_
  39. %   Grave accent  \`     Left brace    \{     Vertical bar  \|
  40. %   Right brace   \}     Tilde         \~}
  41. % \section{Disclaimers, Guidelines and Other Comments}
  42. % \paragraph*{Disclaimer}
  43. % These macros are extensive and were written hurriedly. Only modest attempts
  44. % have been made to clean up and optimize the code. The internals may change
  45. % substantially until version 1.0 comes up.
  46. % \paragraph*{PostScript Guidelines}
  47. % The following guidelines were followed for macros using PostScript
  48. % "\special"'s:
  49. % \begin{enumerate}
  50. % \item Almost no "gsave" and "grestore" commands are used (reducing the
  51. % likelihood of conflicts with dvi-to-ps drivers or an unmatched "gsave" or
  52. % "grestore" ending up on a page).
  53. % \item Most end-user macros (those without "@") have error-checking so that
  54. % bad arguments or other misuse will not generate PostScript errors.
  55. % \end{enumerate}
  56. % \iffalse
  57. % \paragraph*{Prefixes}
  58. % (This list is not complete.) Here are the conventions on prefixes, such as
  59. % the "pst" is "\pst@Verb":
  60. % \begin{center}
  61. % \begin{tabular}{ll}
  62. % {\em Prefix} & {\em Use}\\
  63. % "pst" & This and that.\\
  64. % "psk" & Graphics parameters ("k"={\em key}).\\
  65. % "psset" & Macros that set graphics parameters.\\
  66. % "psls" & Line styles.\\
  67. % "psfs" & Fill styles.\\
  68. % "psas" & Arrow styles.\\
  69. % "pscs" & Custom styles.\\
  70. % \end{tabular}
  71. % \end{center}
  72. % \fi
  73. % \paragraph*{Macros}
  74. % A ``macro'' means any command sequence that is documented in this with a
  75. % heading entry. Macros with "@" are internal, and others are part of the user
  76. % interface. Commands that are not in the heading preceding their definition
  77. % are internal commands of a macro, and are not meant to be used directly by
  78. % other macros.
  79. % \paragraph*{Local and global variables}
  80. % There are various classes of scratch registers and commands:
  81. % \begin{description}
  82. % \item[Global] These can be changed using "\global", etc.
  83. % \begin{LVerbatim}
  84. %   \pst@tempg
  85. %   \pst@temph
  86. %   \pst@dimg
  87. %   \pst@dimh
  88. %   \pst@cntg
  89. %   \pst@cnth
  90. %   \pst@boxg
  91. % \end{LVerbatim}
  92. % \item[Local-I] These cannot be changed with "\global", but otherwise there
  93. % are no restrictions.
  94. % \begin{LVerbatim}
  95. %   \next
  96. %   \@tempa
  97. % \end{LVerbatim}
  98. % \item[Local-I]
  99. % Changes to these must be local to the macro in which they occur (be
  100. % grouping).
  101. % \begin{LVerbatim}
  102. %   \pst@tempa
  103. %   \pst@tempb
  104. %   \pst@tempc
  105. %   \pst@tempd
  106. % \end{LVerbatim}
  107. % \item[Local-II] Changes to these must be local to the macro in which they
  108. % occur, and it must be possible to use these as arguments of macros.
  109. % \begin{LVerbatim}
  110. %   \pst@dima
  111. %   \pst@dimb
  112. %   \pst@dimc
  113. %   \pst@dimd
  114. %   \if@pst
  115. % \end{LVerbatim}
  116. % There is one exception. When using these in coordinates that are processed
  117. % directly as Cartesian coordinates rather than with "\pst@getcoor", they must
  118. % be used in this order:
  119. % \begin{LVerbatim}
  120. %    (\pst@dima,\pst@dimb)(\pst@dimc,\pst@dimd)
  121. % \end{LVerbatim}
  122. % \item[Shared] These are used to share information between macros. Their
  123. % value may be set by one macro and then used by another. Use with care. Do
  124. % not set with "\global".
  125. % \begin{quote}
  126. %  \begin{tabular}{ll}
  127. %    \em command & \em usage\\
  128. %    "\pst@hbox" & Box created and manipulated in HR-box macros.\\
  129. %    "\pst@coor" & PostScript code for a coordinate.\\
  130. %    "\pst@angle" & PostScript code for an angle.\\
  131. %    "\pst@rot"  & PostScript code for a rotation angle.\\
  132. %    "\if@star" & This is a flag to keep track of optional "*".
  133. %  \end{tabular}
  134. % \end{quote}
  135. % \end{description}
  136. % \paragraph*{Plain \TeX\ commands}
  137. % The commands
  138. % \begin{LVerbatim}
  139. %   \newbox
  140. %   \newcount
  141. %   \newdimen
  142. %   \newif
  143. %   \loop ... \repeat ... \fi
  144. %   \z@
  145. %   \sixt@@n
  146. %\end{LVerbatim}
  147. % are defined in "plain.tex" are part of most macro packages. PSTricks assumes
  148. % that they are defined. Other than these, PSTricks only makes use of \TeX\
  149. % primitives.
  150. % \paragraph*{Dividing the file}
  151. % {\bf\em Breaking up the file}\hskip 1em "pstricks.tex" can be broken up into
  152. % the following components:
  153. % \begin{description}
  154. % \item[Basics] (Including color and simple rotation.) Sections \ref{Prelim},
  155. % \ref{Config}, \ref{Header}, \ref{Errors}, \ref{Colors}, \ref{Colortab},
  156. % \ref{Rotation:simple} and \ref{Config:revisited}.
  157. % \item[Graphics] Sections \ref{Parameters}, \ref{Objects}, \ref{Linestyles},
  158. % \ref{Arrowheads}, \ref{Lines}, \ref{Grids}, \ref{Fillstyles}, \ref{Frames},
  159. % \ref{Frameboxes} and \ref{Circles}. Requires also {\bf Basics}.
  160. % \item[Rotation] (Including picture environment.) Sections \ref{Arithmetic},
  161. % \ref{Rotation:prelim}, \ref{Rotation:main} and \ref{Pictures}. Requires also
  162. % {\bf Basics}.
  163. % \end{description}
  164. % \section{Preliminaries\label{Prelim}}
  165. % Check whether file has been loaded already.
  166. %    \begin{macrocode}
  167. \csname PSTricksLoaded\endcsname
  168. \let\PSTricksLoaded\endinput
  169. %    \end{macrocode}
  170. % Take care of the catcode of "@":
  171. %    \begin{macrocode}
  172. \edef\PstAtCode{\the\catcode`\@}
  173. \catcode`\@=11\relax
  174. %    \end{macrocode}
  175. % Here are some hacks borrowed from \LaTeX{}, which are defined if \LaTeX{} is
  176. % not being used.
  177. %    \begin{macrocode}
  178. \expandafter\ifx\csname @latexerr\endcsname\relax
  179.   \long\def\@ifundefined#1#2#3{\expandafter\ifx\csname
  180.     #1\endcsname\relax#2\else#3\fi}
  181.   \def\@namedef#1{\expandafter\def\csname #1\endcsname}
  182.   \def\@nameuse#1{\csname #1\endcsname}
  183.   \def\@eha{%
  184.     Your command was ignored.^^J
  185.     Type \space I <command> <return> \space to replace
  186.     it with another command,^^J
  187.     or \space <return> \space to continue without it.}
  188.   \def\@spaces{\space\space\space\space}
  189.   \def\typeout#1{\immediate\write\@unused{#1}}
  190.   \alloc@7\write\chardef\sixt@@n\@unused
  191.   \def\@empty{}
  192.   \def\@gobble#1{}
  193.   \def\@nnil{\@nil}
  194.   \def\@ifnextchar#1#2#3{%
  195.     \let\@tempe#1\def\@tempa{#2}\def\@tempb{#3}\futurelet\@tempc\@ifnch}
  196.   \def\@ifnch{%
  197.     \ifx\@tempc\@sptoken
  198.       \let\@tempd\@xifnch
  199.     \else
  200.       \ifx\@tempc\@tempe \let\@tempd\@tempa \else \let\@tempd\@tempb \fi
  201.     \fi
  202.     \@tempd}
  203.   \begingroup
  204.     \def\:{\global\let\@sptoken= } \:
  205.     \def\:{\@xifnch} \expandafter\gdef\: {\futurelet\@tempc\@ifnch}
  206.   \endgroup
  207. %    \end{macrocode}
  208. % Announce that the file is being loaded:
  209. %    \begin{macrocode}
  210. \typeout{`PSTricks' v\fileversion\space\space <\filedate> (tvz)}
  211. %    \end{macrocode}
  212. % \section{Error messages}
  213. % \begin{macro}{\@pstrickserr}
  214. % "\@pstrickserr" is analogous to "\@latexerr".
  215. %    \begin{macrocode}
  216. \def\@pstrickserr#1#2{%
  217.   \begingroup
  218.     \newlinechar`\^^J
  219.     \edef\pst@tempc{#2}%
  220.     \expandafter\errhelp\expandafter{\pst@tempc}%
  221.     \typeout{%
  222.       PSTricks error. \space See User's Guide for further information.^^J
  223.       \@spaces\@spaces\@spaces\@spaces
  224.       Type \space H <return> \space for immediate help.}%
  225.     \errmessage{#1}%
  226.   \endgroup}
  227. %    \end{macrocode}
  228. % \end{macro}
  229. % \begin{macro}{\@ehpa,\@ehpb,\@ehpc}
  230. % Here are some extra "\errhelp" message:
  231. %    \begin{macrocode}
  232. \def\@ehpa{%
  233.   Your command was ignored. Default value substituted.^^J
  234.   Type \space <return> \space to procede.}
  235. \def\@ehpb{%
  236.   Your command was ignored. Will recover best I can.^^J
  237.   Type \space <return> \space to procede.}
  238. \def\@ehpc{%
  239.   You better fix this before proceding.^^J
  240.   See the PSTricks User's Guide or ask your system administrator for help.^^J
  241.   Type \space X <return> \space to quit.}
  242. %    \end{macrocode}
  243. % \end{macro}
  244. % \begin{macro}{\pst@misplaced}
  245. %    \begin{macrocode}
  246. \def\pst@misplaced#1{\@pstrickserr{Misplaced \string#1 command}\@ehpb}
  247. %    \end{macrocode}
  248. % \end{macro}
  249. % \section{Scratch registers}
  250. %    \begin{macrocode}
  251. \newdimen\pst@dima
  252. \newdimen\pst@dimb
  253. \newdimen\pst@dimc
  254. \newdimen\pst@dimd
  255. \newdimen\pst@dimg
  256. \newdimen\pst@dimh
  257. \newbox\pst@hbox
  258. \newbox\pst@boxg
  259. \newcount\pst@cnta
  260. \newcount\pst@cntb
  261. \newcount\pst@cntc
  262. \newcount\pst@cntd
  263. \newcount\pst@cntg
  264. \newcount\pst@cnth
  265. \newif\if@pst
  266. %    \end{macrocode}
  267. % \section{Useful hacks}
  268. % \begin{macro}{\pst@ifstar,\if@star}
  269. %    \begin{macrocode}
  270. \newif\if@star
  271. \def\pst@ifstar#1{%
  272.   \@ifnextchar*{\@startrue\def\next*{#1}\next}{\@starfalse#1}}
  273. %    \end{macrocode}
  274. % \end{macro}
  275. % \begin{macro}{\pst@expandafter}
  276. %    \begin{macrocode}
  277. \def\pst@expandafter#1#2{%
  278.   \def\next{#1}%
  279.   \edef\@tempa{#2}%
  280.   \ifx\@tempa\@empty
  281.     \@pstrickserr{Unexpected empty argument!}\@ehpb
  282.     \def\@tempa{\@empty}%
  283.   \fi
  284.   \expandafter\next\@tempa}
  285. %    \end{macrocode}
  286. % \end{macro}
  287. % \section{Arithmetic}
  288. % \begin{macro}{\pst@dimtonum,\pst@@dimtonum}
  289. % This macro strips the value of "#1", a dimension register, of the "pt", and
  290. % assigns the result to "#2", a command sequence. This is used for arithmetic
  291. % and for converting \TeX\ dimensions to PostScript.
  292. %    \begin{macrocode}
  293. \def\pst@dimtonum#1#2{\edef#2{\pst@@dimtonum#1}}
  294. \def\pst@@dimtonum#1{\expandafter\pst@@@dimtonum\the#1}
  295. {\catcode`\p=12 \catcode`\t=12 \global\@namedef{pst@@@dimtonum}#1pt{#1}}
  296. %    \end{macrocode}
  297. % \end{macro}
  298. % \begin{macro}{\pst@pyth}
  299. % This is a piecewise-linear approximation to $("#1"^2+"#2"^2)^(1/2)$. The
  300. % answer is assigned to "#3". All arguments should be dimension registers.
  301. %    \begin{macrocode}
  302. \def\pst@pyth#1#2#3{%
  303.   \ifdim#1>#2\pst@@pyth#1#2#3\else\pst@@pyth#2#1#3\fi}
  304. \def\pst@@pyth#1#2#3{%
  305.   \ifdim4#1>9#2%
  306.     #3=#1\advance#3 .2122#2%
  307.   \else
  308.     #3=.8384#1\advance#3 .5758#2%
  309.   \fi}
  310. %    \end{macrocode}
  311. % \end{macro}
  312. % \begin{macro}{\pst@divide}
  313. % This computes "#3"="#1"/"#2" reasonably quickly. "#1" and "#2" should be
  314. % dimensions, and "#3" should be a command sequence.
  315. %    \begin{macrocode}
  316. \def\pst@divide#1#2#3{%
  317.   \begingroup
  318.     \pst@dimg=#1\relax\pst@dimh=#2\relax
  319.     \pst@cnta=\pst@dimg
  320.     \pst@cntb=1073741824
  321.     \pst@cntc=65536
  322.     \def\pst@tempa{\fi\ifnum}%
  323.     \loop\ifnum\pst@cnta<\pst@cntb
  324.       \pst@tempa\pst@cntc>\@ne
  325.       \multiply\pst@cnta2\divide\pst@cntc2
  326.     \repeat
  327.     \divide\pst@dimh\pst@cntc
  328.     \divide\pst@cnta\pst@dimh
  329.     \global\pst@dimg\number\pst@cnta sp
  330.   \endgroup
  331.   \pst@dimtonum\pst@dimg#3}
  332. %    \end{macrocode}
  333. % \end{macro}
  334. % \section{Configuration file\label{Config}}
  335. % \begin{macro}{\pst@configerr}
  336. %    \begin{macrocode}
  337. \def\pst@configerr#1{%
  338.   \@pstrickserr{\string#1 not defined in pstricks.con}\@ehpc}
  339. %    \end{macrocode}
  340. % \end{macro}
  341. % %    \begin{macrocode}
  342. \def\pstVerb#1{\pst@configerr\pstVerb}
  343. \def\pstverb#1{\pst@configerr\pstverb}
  344. \def\pstverbscale{\pst@configerr\pstverbscale}
  345. \def\pstrotate{\pst@configerr\pstrotate}
  346. \def\pstheader#1{\pst@configerr\pstheader}
  347. \def\pstdriver{\pst@configerr\pstdriver}
  348. \@ifundefined{pstcustomize}%
  349.   {\def\pstcustomize{\endinput\let\pstcustomize\relax}}{}
  350. \input pstricks.con
  351. %    \end{macrocode}
  352. % \begin{macro}{\PSTricksOff}
  353. %    \begin{macrocode}
  354. \newif\ifPSTricks
  355. \PSTrickstrue
  356. \def\PSTricksOff{%
  357.   \def\pstheader##1{}%
  358.   \def\pstverb##1{}%
  359.   \def\pstVerb##1{}%
  360.   \PSTricksfalse}
  361. %    \end{macrocode}
  362. % \end{macro}
  363. % \section{PostScript header file\label{Header}}
  364. % \begin{macro}{\pst@def,\pst@ATH,\pst@useheader}
  365. % There are three ways to use PSTricks:
  366. % \begin{enumerate}
  367. %   \item Use "pstricks.doc" directly. No header file is used.
  368. % \item Use "\pst-make.tex" to generate a stripped input file for use without
  369. % a header.
  370. % \item Use "\pst-make.tex" to generate a header and a stripped input file for
  371. % use with the header.
  372. % \end{enumerate}
  373. % PSTricks has been optimized for use with a header file (and the difference
  374. % is speed and memory is very significant), but the flexible system described
  375. % above makes it easier to maintain the code and allows one to use PSTricks
  376. % with a DVI-to-PS driver that does not support header files.
  377. % The following commands should be used in this ".doc" file for PostScript
  378. % macros and other goodies related to the header file. Their behavior for each
  379. % of the three cases list above is given below. These commands should always
  380. % come {\em at the beginning of the line}, and should not inside conditionals.
  381. % \begin{itemize}
  382. % \item "\pst@def{foo}<bar>"
  383. %   \begin{enumerate}
  384. %     \item "\tx@foo" is defined to be "bar".
  385. %     \item Writes
  386. % \begin{LVerbatim}
  387. %   \def\tx@foo{bar}
  388. % \end{LVerbatim}
  389. %     to "pstricks.tex".
  390. %     \item Writes
  391. % \begin{LVerbatim}
  392. %    /foo { bar } def
  393. % \end{LVerbatim}
  394. %     to "pstricks.pro" and
  395. % \begin{LVerbatim}
  396. %   \def\tx@foo{foo}
  397. % \end{LVerbatim}
  398. %     to "pstricks.tex".
  399. %   \end{enumerate}
  400. % \item "\pst@ATH<foo>"
  401. %   \begin{enumerate}
  402. %     \item Gobbles "foo".
  403. %     \item Ignores line.
  404. %     \item Writes "foo" to "pstricks.pro".
  405. %   \end{enumerate}
  406. %   Note: "\pst@ATH" must come at the beginning of the line.
  407. % \item "\ifx\pst@useheader\iftrue foo \else bar \fi"
  408. %   \begin{enumerate}
  409. %     \item Ignores "foo" and includes "bar".
  410. %     \item Ignores "foo" and processes "bar".
  411. %     \item Processes "foo" and ignores "bar".
  412. %   \end{enumerate}
  413. % Note: "\ifx\pst@useheader\iftrue", "\else" and "\fi" must each be on their
  414. % own line.
  415. % \end{itemize}
  416. % "pst@make.tex" can be used to process other files at well, in the right
  417. % order.
  418. %   \begin{macrocode}
  419. \@ifundefined{pst@def}{\def\pst@def#1<#2>{\@namedef{tx@#1}{#2 }}}{}
  420. \@ifundefined{pst@ATH}{\def\pst@ATH<#1>{}}{}
  421. %    \end{macrocode}
  422. % \end{macro}
  423. % \begin{macro}{\pst@dict}
  424. % The PostScript dictionary "tx@Dict" is set up in the header file, if one is
  425. % used. Otherwise, it is set up with each procedure that uses the dictionary,
  426. % if it is not currently defined.
  427. %    \begin{macrocode}
  428. \pst@ATH<\% Version \fileversion, \filedate.>
  429. \pst@ATH<\% For use with \pstdriver.>
  430. \pst@ATH</tx@Dict 200 dict def tx@Dict begin>
  431. \pst@ATH</ADict 25 dict def>
  432. \pst@ATH</CM { matrix currentmatrix } bind def>
  433. \pst@ATH</SLW /setlinewidth load def>
  434. \pst@ATH</CLW /currentlinewidth load def>
  435. \pst@ATH</CP /currentpoint load def>
  436. \pst@ATH</ED { exch def } bind def>
  437. \pst@ATH</L /lineto load def>
  438. \pst@ATH</T /translate load def>
  439. \ifx\pst@useheader\iftrue
  440.   \pstheader{pstricks.pro}
  441.   \def\pst@dict{tx@Dict begin }
  442.   \def\pst@theheaders{pstricks.pro}
  443. \else
  444.   \def\pst@dict{%
  445.     /tx@Dict where
  446.     { pop tx@Dict begin}
  447.     { userdict begin
  448.         /tx@Dict 200 dict def
  449.       end
  450.       tx@Dict begin
  451.         /ADict 25 dict def
  452.         /CM { matrix currentmatrix } bind def
  453.         /SLW /setlinewidth load def
  454.         /CLW /currentlinewidth load def
  455.         /CP /currentpoint load def
  456.         /ED { exch def } bind def
  457.         /L /lineto load def }
  458.     ifelse }
  459.   \def\pst@theheaders{}%
  460. %    \end{macrocode}
  461. % \end{macro}
  462. % \begin{macro}{\pst@Verb}
  463. %    \begin{macrocode}
  464. \def\pst@Verb#1{\pstVerb{\pst@dict #1 end}}
  465. %    \end{macrocode}
  466. % \end{macro}
  467. % \section{PostScript hacks}
  468. % \begin{macro}{\tx@Atan,\tx@Div}
  469. % These are variants of "atan", and "div", that recover when result is not
  470. % defined.
  471. %    \begin{macrocode}
  472. \pst@def{Atan}</atan load stopped { pop pop 0 } if>
  473. \pst@def{Div}<dup 0 eq { pop } { div } ifelse>
  474. %    \end{macrocode}
  475. % \end{macro}
  476. % \begin{macro}{\tx@NET}
  477. %    \begin{macrocode}
  478. \pst@def{NET}<neg exch neg exch T>
  479. %    \end{macrocode}
  480. % \end{macro}
  481. % \begin{macro}{\tx@Pyth}
  482. % $A$ $B$ "Pyth" $(A^2 + B^2)^{1/2}$
  483. %    \begin{macrocode}
  484. \pst@def{Pyth}<dup mul exch dup mul add sqrt>
  485. %    \end{macrocode}
  486. % \end{macro}
  487. % \begin{macro}{\tx@PtoC}
  488. % Polar to Cartesian:
  489. % \begin{LVerbatim}
  490. %   <r> <a> PtoC <x> <y>
  491. % \end{LVerbatim}
  492. %    \begin{macrocode}
  493. \pst@def{PtoC}<2 copy cos mul 3 1 roll sin mul>
  494. %    \end{macrocode}
  495. % \end{macro}
  496. % \begin{macro}{\tx@PathLength}
  497. % "PathLength" is taken from the Blue Book. It leaves on the stack the length
  498. % of the current path.
  499. %    \begin{macrocode}
  500. \pst@def{PathLength@}<%
  501.   /z z y y1 sub x x1 sub \tx@Pyth add def
  502.   /y1 y def /x1 x def>
  503. \pst@def{PathLength}<%
  504.   flattenpath /z 0 def
  505.   { /y1 ED /x1 ED /y2 y1 def /x2 x1 def } % moveto
  506.   { /y ED /x ED \tx@PathLength@ } % lineto
  507.   {} % curveto; ignore because of flattenpath.
  508.   { /y y2 def /x x2 def \tx@PathLength@ } % closepath
  509.   pathforall z>
  510. %    \end{macrocode}
  511. % \end{macro}
  512. % \section{Converting \TeX\ things to PostScript}
  513. % \begin{macro}{\pst@number,\tx@STP,\tx@STV}
  514. % \begin{itemize}
  515. % \item PSTricks' PostScript unit is 1pt, rather than 1bp, because this is
  516. % more efficient.
  517. % \item "\pst@number{<dimen register>}" converts <dimen> to PostScript, in
  518. % points (pt).
  519. % \item "\tx@STP" scales the DVI-to-PS driver's "\pstverb" environment to
  520. % points (pt).
  521. % \item "\tx@STV" scales the DVI-to-PS drivers's ungrouped PostScript
  522. % "\special" environment ("\pstVerb") to points (pt).
  523. % \end{itemize}
  524. %    \begin{macrocode}
  525. \pst@dimg=\pstunit\relax
  526. \ifdim\pst@dimg=1bp
  527.   \def\pst@stp{.996264 dup scale}
  528. \else
  529.   \edef\pst@stp{1 \pst@@dimtonum\pst@dimg\space div dup scale}
  530. \pst@def{STP}<\pst@stp>
  531. \pst@def{STV}<\pstverbscale\space\tx@STP>
  532. \def\pst@number#1{\pst@@dimtonum#1\space}
  533. %    \end{macrocode}
  534. % \end{macro}
  535. % \begin{macro}{\pst@checknum}
  536. % The first argument of "\pst@checknum" should be a number, and the second
  537. % argument is a command. There are three possible outcomes:
  538. % \begin{enumerate}
  539. % \item The number is suitable for PostScript consumption, the command is set
  540. % to the number, and "\pst@num" is set to "1" if the number is positive and to
  541. % "2" if the number is negative.
  542. % \item "\pst@checknum" detects that the number is not suitable for
  543. % PostScript; "\pst@num" is set to "0", an error is given, and the command is
  544. % defined to be {\tt 0 }.
  545. % \item The number is not suitable for PostScript consumption, but
  546. % "\pst@checknum" does not detect this. "\pst@num" is set to "1" or "2", and
  547. % the command is set to some number that {\em is} suitable for PostScript.
  548. % \end{enumerate}
  549. % A trailing space is always added.
  550. % "\pst@checknum" should generate no extraneous errors nor output, even if the
  551. % first argument is a bad number.
  552. % This macro is probably pretty close to optimal for what it does, as many
  553. % variations have been tried.
  554. %    \begin{macrocode}
  555. \def\pst@checknum#1#2{%
  556.   \edef\next{#1}%
  557.   \ifx\next\@empty
  558.     \let\pst@num\z@
  559.   \else
  560.     \expandafter\pst@@checknum\next..\@nil
  561.   \fi
  562.   \ifnum\pst@num=\z@
  563.     \@pstrickserr{Bad number: `#1'. 0 substituted.}\@ehpa
  564.     \def#2{0 }%
  565.   \else
  566.     \edef#2{\ifnum\pst@num=2 -\fi\the\pst@cntg.%
  567.       \expandafter\@gobble\the\pst@cnth\space}%
  568.   \fi}
  569. \def\pst@@checknum{%
  570.   \@ifnextchar-%
  571.     {\def\pst@num{2}\expandafter\pst@@@checknum\@gobble}%
  572.     {\def\pst@num{1}\pst@@@checknum}}
  573. \def\pst@@@checknum#1.#2.#3\@nil{%
  574.   \afterassignment\pst@@@@checknum\pst@cntg=0#1\relax\@nil
  575.   \afterassignment\pst@@@@checknum\pst@cnth=1#2\relax\@nil}
  576. \def\pst@@@@checknum#1\relax\@nil{%
  577.   \ifx\@nil#1\@nil\else\let\pst@num\z@\fi}
  578. %    \end{macrocode}
  579. % \end{macro}
  580. % \begin{macro}{\pst@getnumii,\pst@getnumiii,\pst@getnumiv}
  581. % These are for processing comma-separated lists of numbers. They assign the
  582. % numbers to "\pst@tempg", "\pst@temph", etc. Use like
  583. % \begin{LVerbatim}
  584. %   \pst@expandafter\pst@getnumiii{foo} {} {} {} {}\@ni
  585. % \end{LVerbatim}
  586. % If there are too few numbers, an error results. If there are too many, the
  587. % extra numbers are ignored.
  588. %    \begin{macrocode}
  589. \def\pst@getnumii#1 #2 #3\@nil{%
  590.   \pst@checknum{#1}\pst@tempg
  591.   \pst@checknum{#2}\pst@temph}
  592. \def\pst@getnumiii#1 #2 #3 #4\@nil{%
  593.   \pst@checknum{#1}\pst@tempg
  594.   \pst@checknum{#2}\pst@temph
  595.   \pst@checknum{#3}\pst@tempi}
  596. \def\pst@getnumiv#1 #2 #3 #4 #5\@nil{%
  597.   \pst@checknum{#1}\pst@tempg
  598.   \pst@checknum{#2}\pst@temph
  599.   \pst@checknum{#3}\pst@tempi
  600.   \pst@checknum{#4}\pst@tempj}
  601. %    \end{macrocode}
  602. % \end{macro}
  603. % \begin{macro}{\pst@getdimnum}
  604. % Like "\pst@getnumii", but first item is a dimension and second is a number.
  605. %    \begin{macrocode}
  606. \def\pst@getdimnum#1 #2 #3\@nil{%
  607.   \pssetlength\pst@dimg{#1}%
  608.   \pst@checknum{#2}\pst@tempg}
  609. %    \end{macrocode}
  610. % \end{macro}
  611. % \begin{macro}{\pst@getscale}
  612. % "\pst@getscale" can have one or two numbers in its first argument.
  613. %    \begin{macrocode}
  614. \def\pst@getscale#1#2{%
  615.   \pst@expandafter\pst@getnumii{#1 #1} {} {} {}\@nil
  616.   \edef#2{\pst@tempg\space \pst@temph\space scale }%
  617.   \ifdim\pst@tempg\p@=\z@
  618.     \@pstrickserr{Bad scaling argument `#1'}\@ehpa
  619.     \def#2{}%
  620.   \else
  621.     \ifdim\pst@temph\p@=\z@
  622.       \@pstrickserr{Bad scaling argument}\@ehpa
  623.       \def#2{}%
  624.     \else
  625.       \ifdim\pst@tempg\p@=\p@ \ifdim\pst@temph\p@=\p@ \def#2{}\fi\fi
  626.     \fi
  627.   \fi}
  628. %    \end{macrocode}
  629. % \end{macro}
  630. % \begin{macro}{\pst@getint}
  631. %    \begin{macrocode}
  632. \def\pst@getint#1#2{%
  633.   \pst@cntg=#1\relax
  634.   \edef#2{\the\pst@cntg\space}}
  635. %    \end{macrocode}
  636. % \end{macro}
  637. % \begin{macro}{\pslbrace,\psrbrace}
  638. % When balanced braces are used, they work without problems in "\special"'s.
  639. % "\pslbrace" and "\psrbrace" let you use unbalanced braces.
  640. %    \begin{macrocode}
  641. \begingroup
  642.   \catcode`\{=12
  643.   \catcode`\}=12
  644.   \catcode`\[=1
  645.   \catcode`\]=2
  646.   \gdef\pslbrace[{ ]
  647.   \gdef\psrbrace[} ]
  648. \endgroup
  649. %    \end{macrocode}
  650. % \end{macro}
  651. % \section{Colors\label{Colors}}
  652. % \begin{macro}{\@newcolor}
  653. % "\@newcolor{<color>}{<spec>}", where <color> is a name and <spec> is the
  654. % associated PostScript color specification , sets
  655. % \begin{itemize}
  656. %   \item "\<color>" to "\pst@color{<spec>}", and
  657. %   \item "\color@<color>" to <spec>.
  658. % \end{itemize}
  659. % Then "\<color>" can be used by the user to color text, etc., and
  660. % "\color@<color>" is used by PSTricks graphics objects to find the
  661. % specification for <color>.
  662. %    \begin{macrocode}
  663. \def\@newcolor#1#2{%
  664.   \expandafter\edef\csname #1\endcsname{\noexpand\pst@color{#2}}%
  665.   \expandafter\edef\csname color@#1\endcsname{#2}%
  666.   \ignorespaces}
  667. %    \end{macrocode}
  668. % \end{macro}
  669. % \begin{macro}{\pst@color,\pst@endcolor}
  670. % The argument of "\pst@color" should be a PostScript command for setting the
  671. % color; e.g., "0 setgray". It saves the command in "\pst@currentcolor", and
  672. % then switches to "\pst@currentcolor" at the end of the current group. The
  673. % color changes do not extend across pages, although this capability could be
  674. % written into the output routines (so that "\pst@currentcolor" is set at the
  675. % beginning of the page, and headers and footers begin with "\black", etc.).
  676. % Moving boxes cause problems, but there is no way around this until \TeX{}
  677. % supports color internally.
  678. %    \begin{macrocode}
  679. \def\pst@color#1{%
  680.   \def\pst@currentcolor{#1}\pstVerb{#1}\aftergroup\pst@endcolor}
  681. \def\pst@endcolor{\pstVerb{\pst@currentcolor}}
  682. \def\pst@currentcolor{0 setgray}
  683. %    \end{macrocode}
  684. % \end{macro}
  685. % \begin{macro}{\altcolormode,\pst@grestore}
  686. % The color macros defined above can conflict with other color macros.
  687. % "\altcolormode" sets up a different scheme that uses "gsave" and "grestore"
  688. % to reset colors. This may reduce the likelihood of such conflict. It also
  689. % makes moving boxes less of a problem, as long as the color command is itself
  690. % grouped within the box. However, if the scope of a color command extends
  691. % across pages in a \TeX{} input file, unmatched "gsave"'s and "grestore"'s
  692. % will be left on pages, wreaking havok on the output. "\pst@grestore" is
  693. % defined to do various things that makes using "grestore" more robust.
  694. %    \begin{macrocode}
  695. \def\altcolormode{%
  696.   \def\pst@color##1{%
  697.     \pstVerb{gsave ##1}\aftergroup\pst@endcolor}%
  698.   \def\pst@endcolor{\pstVerb{\pst@grestore}}}
  699. \def\pst@grestore{%
  700.   currentpoint
  701.   matrix currentmatrix
  702.   currentfont
  703.   grestore
  704.   setfont
  705.   setmatrix
  706.   moveto}
  707. %    \end{macrocode}
  708. % \end{macro}
  709. % \begin{macro}{\pst@usecolor}
  710. % This looks up the color specification.
  711. %    \begin{macrocode}
  712. \def\pst@usecolor#1{\csname color@#1\endcsname\space}
  713. %    \end{macrocode}
  714. % \end{macro}
  715. % \begin{macro}{\newgray}
  716. % "\newgray" uses PostScript's "setgray" operator.
  717. %    \begin{macrocode}
  718. \def\newgray#1#2{%
  719.   \pst@checknum{#2}\pst@tempg
  720.   \@newcolor{#1}{\pst@tempg setgray}}
  721. %    \end{macrocode}
  722. % \end{macro}
  723. % \begin{macro}{\newrgbcolor}
  724. % This works like "\newgray", but the color specification should consist of 3
  725. % numbers rather than just 1, and the "setrgbcolor" operator is used.
  726. %    \begin{macrocode}
  727. \def\newrgbcolor#1#2{%
  728.   \pst@expandafter\pst@getnumiii{#2} {} {} {} {}\@nil
  729.   \@newcolor{#1}{\pst@tempg \pst@temph \pst@tempi setrgbcolor}}
  730. %    \end{macrocode}
  731. % \end{macro}
  732. % \begin{macro}{\newhsbcolor}
  733. % This is just like "\newrgbcolor", but the "sethsbcolor" operator is used.
  734. %    \begin{macrocode}
  735. \def\newhsbcolor#1#2{%
  736.   \pst@expandafter\pst@getnumiii{#2} {} {} {} {}\@nil
  737.   \@newcolor{#1}{\pst@tempg \pst@temph \pst@tempi sethsbcolor}}
  738. %    \end{macrocode}
  739. % \end{macro}
  740. % \begin{macro}{\newcmykcolor}
  741. % This is like "\newrgbcolor", the color specification consists of 4 numbers
  742. % and the "setcmykcolor" operator is used.
  743. %    \begin{macrocode}
  744. \def\newcmykcolor#1#2{%
  745.   \pst@expandafter\pst@getnumiv{#2} {} {} {} {} {}\@nil
  746.   \@newcolor{#1}{\pst@tempg \pst@temph \pst@tempi \pst@tempj setcmykcolor}}
  747. %    \end{macrocode}
  748. % \end{macro}
  749. % \begin{macro}{\black,\darkgray,\gray,\lightgray,\white}
  750. % Here are some default gray definitions:
  751. %    \begin{macrocode}
  752. \newgray{black}{0}
  753. \newgray{darkgray}{.25}
  754. \newgray{gray}{.5}
  755. \newgray{lightgray}{.75}
  756. \newgray{white}{1}
  757. %    \end{macrocode}
  758. % \end{macro}
  759. % \begin{macro}{\red,\green,\blue,\yellow,\cyan,\magenta}
  760. % And some default rgb color definitions.
  761. %    \begin{macrocode}
  762. \newrgbcolor{red}{1 0 0}
  763. \newrgbcolor{green}{0 1 0}
  764. \newrgbcolor{blue}{0 0 1}
  765. \newrgbcolor{yellow}{1 1 0}
  766. \newrgbcolor{cyan}{0 1 1}
  767. \newrgbcolor{magenta}{1 0 1}
  768. %    \end{macrocode}
  769. % \end{macro}
  770. % \section{Setting graphics parameters\label{Parameters}}
  771. % \begin{macro}{\psset}
  772. % For each <parameter>"="<value> pair in its argument, "\psset" invokes
  773. % \begin{LVerbatim}
  774. %   \psset@<parameter>{<value>}
  775. % \end{LVerbatim}
  776. % The value is processed and typically stored in "\ps<parameters>" if the
  777. % value is user-accessible and "\psk@<parameter>" if not. "\psset" ignores
  778. % spaces that follow the comma that separates key-value pairs.
  779. % When initializing <parameter> in this file, preferable use
  780. % \begin{LVerbatim}
  781. %   \psset@<parameter>{<value>}
  782. % \end{LVerbatim}
  783. % so that default values can be easily extracted for the {\em User's Guide}.
  784. %   \begin{macrocode}
  785. \def\psset#1{\@psset#1,\@nil\ignorespaces}
  786. \def\@psset#1,{%
  787.   \@@psset#1==\@nil
  788.   \@ifnextchar\@nil{\@gobble}{\@psset}}
  789. \def\@@psset#1=#2=#3\@nil{%
  790.   \@ifundefined{psset@#1}%
  791.     {\@pstrickserr{Graphics parameter `#1' not defined.}\@ehpa}%
  792.     {\@nameuse{psset@#1}{#2}}}%
  793. %    \end{macrocode}
  794. % \end{macro}
  795. % \begin{macro}{\newpsstyle}
  796. %    \begin{macrocode}
  797. \def\psset@style#1{%
  798.   \@ifundefined{pscs@#1}%
  799.     {\@pstrickserr{Custom style `#1' undefined}\@ehpa}%
  800.     {\@nameuse{pscs@#1}}}
  801. \def\newpsstyle#1#2{\@namedef{pscs@#1}{\psset{#2}}}
  802. %    \end{macrocode}
  803. % \end{macro}
  804. % \begin{macro}{\@none}
  805. % Use to check when a parameter value is "none".
  806. %    \begin{macrocode}
  807. \def\@none{none}
  808. %    \end{macrocode}
  809. % \end{macro}
  810. % \begin{macro}{\pst@getcolor}
  811. % This is used by various graphics parameters that are colors.
  812. %    \begin{macrocode}
  813. \def\pst@getcolor#1#2{%
  814.   \@ifundefined{color@#1}%
  815.     {\@pstrickserr{Color `#1' not defined}\@eha}%
  816.     {\edef#2{#1}}}
  817. %    \end{macrocode}
  818. % \end{macro}
  819. % \section{Dimensions}
  820. % \begin{macro}{\psunit,\psxunit,\psyunit}
  821. %    \begin{macrocode}
  822. \newdimen\psunit \psunit 1cm
  823. \newdimen\psxunit \psxunit 1cm
  824. \newdimen\psyunit \psyunit 1cm
  825. \let\psrunit\psunit
  826. %    \end{macrocode}
  827. % \end{macro}
  828. % \begin{macro}{\pssetlength,\psaddtolength,\pssetxlength,\pssetylength}
  829. %    \begin{macrocode}
  830. \def\pstunit@off{\let\@psunit\ignorespaces\ignorespaces}
  831. \def\pssetlength#1#2{%
  832.   \let\@psunit\psunit
  833.   \afterassignment\pstunit@off
  834.   #1 #2\@psunit}
  835. \def\psaddtolength#1#2{%
  836.   \let\@psunit\psunit
  837.   \afterassignment\pstunit@off
  838.   \advance#1 #2\@psunit}
  839. \def\pssetxlength#1#2{%
  840.   \let\@psunit\psxunit
  841.   \afterassignment\pstunit@off
  842.   #1 #2\@psunit}
  843. \def\pssetylength#1#2{%
  844.   \let\@psunit\psyunit
  845.   \afterassignment\pstunit@off
  846.   #1 #2\@psunit}
  847. %    \end{macrocode}
  848. % \end{macro}
  849. % \begin{macro}{\psset@unit,\psset@xunit,\psset@yunit}
  850. %    \begin{macrocode}
  851. \def\psset@unit#1{%
  852.   \pssetlength\psunit{#1}%
  853.   \psxunit=\psunit
  854.   \psyunit=\psunit}
  855. \def\psset@runit#1{\pssetlength\psrunit{#1}}
  856. \def\psset@xunit#1{\pssetxlength\psxunit{#1}}
  857. \def\psset@yunit#1{\pssetylength\psyunit{#1}}
  858. %    \end{macrocode}
  859. % \end{macro}
  860. % \begin{macro}{\pst@getlength,pst@@getlength}
  861. % "#1" is a \TeX\ dimensions. "\pst@getlength" sets "#2" to the PostScript
  862. % code for "#1", and "\pst@@getlength" set "#2" to the \TeX\ code for "#1".
  863. %    \begin{macrocode}
  864. \def\pst@getlength#1#2{%
  865.   \pssetlength\pst@dimg{#1}%
  866.   \edef#2{\pst@number\pst@dimg}}
  867. \def\pst@@getlength#1#2{%
  868.   \pssetlength\pst@dimg{#1}%
  869.   \edef#2{\number\pst@dimg sp}}
  870. %    \end{macrocode}
  871. % \end{macro}
  872. % \section{Normal Coordinates and angles}
  873. % \begin{macro}{\pst@getcoor,\pst@coor}
  874. % "\pst@@getcoor" should be defined to read a coordinate and convert it to
  875. % PostScript, assigning the result to "\pst@coor" (including the trailing
  876. % space).
  877. % "\pst@getcoor" invokes "\pst@@getcoor" and then sets its second argument to
  878. % "\pst@coor".
  879. %    \begin{macrocode}
  880. \def\pst@getcoor#1#2{\pst@@getcoor{#1}\let#2\pst@coor}
  881. \def\pst@coor{0 0 }
  882. %    \end{macrocode}
  883. % \end{macro}
  884. % \begin{macro}{\pst@getcoors,\pst@coors}
  885. % "\pst@getcoors" reads coordinates until there are none left, adding them
  886. % {\em in reverse order} to "\pst@coors".
  887. %    \begin{macrocode}
  888. \def\pst@getcoors#1#2{%
  889.   \def\pst@aftercoors{\addto@pscode{#1 \pst@coors }#2}%
  890.   \def\pst@coors{}%
  891.   \pst@@getcoors}
  892. \def\pst@@getcoors(#1){%
  893.   \pst@@getcoor{#1}%
  894.   \edef\pst@coors{\pst@coor\pst@coors}%
  895.   \@ifnextchar({\pst@@getcoors}{\pst@aftercoors}}
  896. %    \end{macrocode}
  897. % \end{macro}
  898. % \begin{macro}{\pst@getangle,\pst@angle}
  899. % \n\pst@@getangle\ should be defined to read an angle and convert it to
  900. % PostScript, assigning the result to \n\pst@angle\ (including the trailing
  901. % space).
  902. % \n\pst@getangle\ invokes \n\pst@@getangle\ and then sets its second argument
  903. % to \n\pst@angle.
  904. %    \begin{macrocode}
  905. \def\pst@getangle#1#2{\pst@@getangle{#1}\let#2\pst@angle}
  906. \def\pst@angle{0 }
  907. %    \end{macrocode}
  908. % \end{macro}
  909. % \begin{macro}{getcoor@c,\NormalCoor}
  910. % By default, coordinates are read as Cartesian coordinates by
  911. % "\cartesian@coor".
  912. % Angles are read as numbers, scaled by \n\pst@angleunit.
  913. % "\NormalCoor" sets these two defaults, and also defines the translation for
  914. % the put commands to be done by \TeX\ using Cartesian coordinates.
  915. %    \begin{macrocode}
  916. \def\cartesian@coor#1,#2,#3\@nil{%
  917.   \pssetxlength\pst@dimg{#1}%
  918.   \pssetylength\pst@dimh{#2}%
  919.   \edef\pst@coor{\pst@number\pst@dimg \pst@number\pst@dimh}}
  920. \def\NormalCoor{%
  921.   \def\pst@@getcoor##1{\pst@expandafter\cartesian@coor{##1},\relax,\@nil}%
  922.   \def\pst@@getangle##1{%
  923.     \pst@checknum{##1}\pst@angle
  924.     \edef\pst@angle{\pst@angle \pst@angleunit}}%
  925.   \def\psput@##1{\pst@@getcoor{##1}\leavevmode\psput@cartesian}}
  926. \NormalCoor
  927. %    \end{macrocode}
  928. % \end{macro}
  929. % \begin{macro}{\pst@angleunit,\degrees,\radians}
  930. % "\degrees" sets "\pst@angleunit" to the PostScript code for scaling the
  931. % angle, including the trailing space.
  932. %    \begin{macrocode}
  933. \def\degrees{\@ifnextchar[{\@degrees}{\def\pst@angleunit{}}}
  934. \def\@degrees[#1]{%
  935.   \pst@checknum{#1}\pst@tempg
  936.   \edef\pst@angleunit{360 \pst@tempg div mul }%
  937.   \ignorespaces}
  938. \def\radians{\def\pst@angleunit{57.2956 mul }}
  939. \def\pst@angleunit{}
  940. %    \end{macrocode}
  941. % \end{macro}
  942. % \section{Special coordinates and angles}
  943. % This is a tedious but useful.
  944. % \begin{macro}{\SpecialCoor}
  945. %    \begin{macrocode}
  946. \def\SpecialCoor{%
  947.   \def\pst@@getcoor##1{\pst@expandafter\special@coor{##1}||\@nil}%
  948.   \def\pst@@getangle##1{\pst@expandafter\special@angle{##1}\@empty)\@nil}%
  949.   \def\psput@##1{\pst@@getcoor{##1}\leavevmode\psput@special}}
  950. %    \end{macrocode}
  951. % \end{macro}
  952. % \begin{macro}{\specialcoor}
  953. %    \begin{macrocode}
  954. \def\special@coor#1|#2|#3\@nil{%
  955.   \ifx#3|\relax
  956.     \mixed@coor{#1}{#2}%
  957.   \else
  958.     \special@@coor#1;;\@nil
  959.   \fi}
  960. \def\special@@coor#1{%
  961.   \ifcat#1a\relax
  962.     \def\next{\node@coor#1}%
  963.   \else
  964.     \ifx#1[\relax
  965.       \def\next{\Node@coor[}%
  966.     \else
  967.       \ifx#1!\relax
  968.         \def\next{\raw@coor}%
  969.       \else
  970.         \def\next{\special@@@coor#1}%
  971.       \fi
  972.     \fi
  973.   \fi
  974.   \next}
  975. \def\special@@@coor#1;#2;#3\@nil{%
  976.   \ifx#3;\relax
  977.     \polar@coor{#1}{#2}%
  978.   \else
  979.     \cartesian@coor#1,\relax,\@nil
  980.   \fi}
  981. %    \end{macrocode}
  982. % \end{macro}
  983. % \begin{macro}{\mixed@coor}
  984. % This allows mixing of coordinate types with \n\SpecialCoor.
  985. %    \begin{macrocode}
  986. \def\mixed@coor#1#2{%
  987.     \begingroup
  988.       \specialcoor@ii#1;;\@nil
  989.       \let\pst@tempa\pst@coor
  990.       \specialcoor@ii#2;;\@nil
  991.       \xdef\pst@tempg{\pst@tempa pop \pst@coor exch pop }%
  992.     \endgroup
  993.     \let\pst@coor\pst@tempg}
  994. %    \end{macrocode}
  995. % \end{macro}
  996. % \begin{macro}{\polar@coor}
  997. % For polar coordinates
  998. %    \begin{macrocode}
  999. \def\polar@coor#1#2{%
  1000.   \pssetlength\pst@dimg{#1}%
  1001.   \pst@@getangle{#2}%
  1002.   \edef\pst@coor{\pst@number\pst@dimg \pst@angle \tx@PtoC}}
  1003. %    \end{macrocode}
  1004. % \end{macro}
  1005. % \begin{macro}{\raw@coor}
  1006. % For raw PostScript.
  1007. %    \begin{macrocode}
  1008. \def\raw@coor#1;#2\@nil{%
  1009.   \edef\pst@coor{%
  1010.     #1 \pst@number\psyunit mul exch \pst@number\psxunit mul exch }}
  1011. %    \end{macrocode}
  1012. % \end{macro}
  1013. % \begin{macro}{\node@coor,\Node@coor}
  1014. % These are defined in "pst-node.tex".
  1015. %    \begin{macrocode}
  1016. \def\node@coor#1\@nil{%
  1017.   \@pstrickserr{You must load `pst-node.tex' to use node coordinates.}\@ehps
  1018.   \def\pst@coor{0 0 }}
  1019. \def\Node@coor{\node@coor}
  1020. %    \end{macrocode}
  1021. % \end{macro}
  1022. % \begin{macro}{\special@angle}
  1023. %    \begin{macrocode}
  1024. \def\special@angle#1#2)#3\@nil{%
  1025.   \ifx#1!\relax
  1026.     \edef\pst@angle{#2 \pst@angleunit}%
  1027.   \else
  1028.     \ifx#1(\relax
  1029.       \pst@@getcoor{#2}%
  1030.       \edef\pst@angle{\pst@coor exch \tx@Atan}%
  1031.     \else
  1032.       \pst@checknum{#1#2}\pst@angle
  1033.       \edef\pst@angle{\pst@angle \pst@angleunit}%
  1034.     \fi
  1035.   \fi}
  1036. %    \end{macrocode}
  1037. % \end{macro}
  1038. % \begin{macro}{\Cartesian,\Polar}
  1039. % These are obsolete.
  1040. %    \begin{macrocode}
  1041. \def\Cartesian{%
  1042.   \def\cartesian@coor##1,##2,##3\@nil{%
  1043.     \pssetxlength\pst@dimg{##1}%
  1044.     \pssetylength\pst@dimh{##2}%
  1045.     \edef\pst@coor{\pst@number\pst@dimg \pst@number\pst@dimh}}%
  1046.   \@ifnextchar({\Cartesian@}{}}
  1047. \def\Cartesian@(#1,#2){%
  1048.   \pssetxlength\psxunit{#1}%
  1049.   \pssetylength\psyunit{#2}%
  1050.   \ignorespaces}
  1051. \def\Polar{%
  1052.   \def\psput@cartesian{\psput@special}%
  1053.   \def\cartesian@coor##1,##2,##3\@nil{\polar@coor{##1}{##2}}}%
  1054. %    \end{macrocode}
  1055. % \end{macro}
  1056. % \section{Basic graphics parameters}
  1057. % \begin{macro}{\psset@origin,\psk@origin}
  1058. %    \begin{macrocode}
  1059. \def\psset@origin#1{%
  1060.   \pst@@getcoor{#1}%
  1061.   \edef\psk@origin{\pst@coor \tx@NET }}
  1062. \def\psk@origin{}
  1063. %    \end{macrocode}
  1064. % \end{macro}
  1065. % \begin{macro}{\psset@swapaxes,\ifpsswapaxes}
  1066. %    \begin{macrocode}
  1067. \newif\ifswapaxes
  1068. \def\psset@swapaxes#1{%
  1069.   \@nameuse{@pst#1}%
  1070.   \if@pst
  1071.     \def\psk@swapaxes{-90 rotate -1 1 scale }%
  1072.   \else
  1073.     \def\psk@swapaxes{}%
  1074.   \fi}
  1075. \psset@swapaxes{false}
  1076. %    \end{macrocode}
  1077. % \end{macro}
  1078. % \begin{macro}{\psset@showpoints,\ifshowpoints}
  1079. %    \begin{macrocode}
  1080. \newif\ifshowpoints
  1081. \def\psset@showpoints#1{\@nameuse{showpoints#1}}
  1082. \psset@showpoints{false}
  1083. %    \end{macrocode}
  1084. % \end{macro}
  1085. % \begin{macro}{\psset@border,\psk@border}
  1086. %    \begin{macrocode}
  1087. \let\pst@setrepeatarrowsflag\relax
  1088. \def\psset@border#1{%
  1089.   \pst@getlength{#1}\psk@border
  1090.   \pst@setrepeatarrowsflag}
  1091. \psset@border{0pt}
  1092. %    \end{macrocode}
  1093. % \end{macro}
  1094. % \begin{macro}{\psset@bordercolor,\psbordercolor}
  1095. %    \begin{macrocode}
  1096. \def\psset@bordercolor#1{\pst@getcolor{#1}\psbordercolor}
  1097. \psset@bordercolor{white}
  1098. %    \end{macrocode}
  1099. % \end{macro}
  1100. % \begin{macro}{\psset@doubleline,\ifpsdoubleline}
  1101. %    \begin{macrocode}
  1102. \newif\ifpsdoubleline
  1103. \def\psset@doubleline#1{%
  1104.   \@nameuse{psdoubleline#1}%
  1105.   \pst@setrepeatarrowsflag}
  1106. \psset@doubleline{false}
  1107. %    \end{macrocode}
  1108. % \end{macro}
  1109. % \begin{macro}{\psset@doublesep,\psdoublesep}
  1110. %    \begin{macrocode}
  1111. \def\psset@doublesep#1{\def\psdoublesep{#1}}
  1112. \psset@doublesep{1.25\pslinewidth}
  1113. %    \end{macrocode}
  1114. % \end{macro}
  1115. % \begin{macro}{\psset@doublecolor,\psdoublecolor}
  1116. %    \begin{macrocode}
  1117. \def\psset@doublecolor#1{\pst@getcolor{#1}\psdoublecolor}
  1118. \psset@doublecolor{white}
  1119. %    \end{macrocode}
  1120. % \end{macro}
  1121. % \begin{macro}{\psset@shadow,\ifpsshadow}
  1122. %    \begin{macrocode}
  1123. \newif\ifpsshadow
  1124. \def\psset@shadow#1{%
  1125.   \@nameuse{psshadow#1}%
  1126.   \pst@setrepeatarrowsflag}
  1127. \psset@shadow{false}
  1128. %    \end{macrocode}
  1129. % \end{macro}
  1130. % \begin{macro}{\psset@shadowsize,\psk@shadowsize}
  1131. %    \begin{macrocode}
  1132. \def\psset@shadowsize#1{\pst@getlength{#1}\psk@shadowsize}
  1133. \psset@shadowsize{3pt}
  1134. %    \end{macrocode}
  1135. % \end{macro}
  1136. % \begin{macro}{\psset@shadowangle,\psk@shadowangle}
  1137. %    \begin{macrocode}
  1138. \def\psset@shadowangle#1{\pst@getangle{#1}\psk@shadowangle}
  1139. \psset@shadowangle{-45}
  1140. %    \end{macrocode}
  1141. % \end{macro}
  1142. % \begin{macro}{\psset@shadowcolor,\psshadowcolor}
  1143. %    \begin{macrocode}
  1144. \def\psset@shadowcolor#1{\pst@getcolor{#1}\psshadowcolor}
  1145. \psset@shadowcolor{darkgray}
  1146. %    \end{macrocode}
  1147. % \end{macro}
  1148. % \begin{macro}{\pst@setrepeatarrowsflag}
  1149. %    \begin{macrocode}
  1150. \def\pst@repeatarrowsflag{\z@}
  1151. \def\pst@setrepeatarrowsflag{%
  1152.   \edef\pst@repeatarrowsflag{%
  1153.     \ifdim\psk@border\p@>\z@ 1\else\ifpsdoubleline 1\else
  1154.     \ifpsshadow 1\else \z@\fi\fi\fi}}
  1155. %    \end{macrocode}
  1156. % \end{macro}
  1157. % \section{Line styles\label{Linestyles}}
  1158. % For each "linestyle" <style>, the command "\psls@<style>" should be the
  1159. % PostScript code that strokes the path. The style can assume that the
  1160. % PostScript environment has linewidth equal to \n\pslinewidth\ and color
  1161. % equal to \n\pslinecolor.
  1162. % \begin{macro}{\pst@linetype}
  1163. % Macros that draw lines should define "\pst@linetype" (not a count register)
  1164. % to be:
  1165. % \begin{description}
  1166. % \item[1,2,$\ldots$] A closed path whose length should be divided by
  1167. % "\pst@linetype" before fitting a pattern.
  1168. % \item[0] A line that has nothing at the tips.
  1169. % \item[-1] A line with an arrow or something at the end.
  1170. % \item[-2] A line with an arrow or something at the beginning.
  1171. % \item[-3] A line with an arrow or something at each end.
  1172. % \end{description}
  1173. % This information is used by the line styles that draw dashed and dotted
  1174. % lines in order to figure out how to adjust the patterns.
  1175. % \end{macro}
  1176. % \begin{macro}{\psls@none}
  1177. %    \begin{macrocode}
  1178. \def\psls@none{}
  1179. %    \end{macrocode}
  1180. % \end{macro}
  1181. % \begin{macro}{\psset@linewidth,\pslinewidth}
  1182. %    \begin{macrocode}
  1183. \newdimen\pslinewidth
  1184. \def\psset@linewidth#1{\pssetlength\pslinewidth{#1}}
  1185. \psset@linewidth{.8pt}
  1186. %    \end{macrocode}
  1187. % \end{macro}
  1188. % \begin{macro}{\psset@linecolor,\pslinecolor}
  1189. %    \begin{macrocode}
  1190. \def\psset@linecolor#1{\pst@getcolor{#1}\pslinecolor}
  1191. \psset@linecolor{black}
  1192. %    \end{macrocode}
  1193. % \end{macro}
  1194. % \begin{macro}{\psls@solid}
  1195. %    \begin{macrocode}
  1196. \def\psls@solid{0 setlinecap stroke }
  1197. %    \end{macrocode}
  1198. % \end{macro}
  1199. % \begin{macro}{\psset@dash,\psk@dash}
  1200. % "\psk@dash" is set to the PostScript code for the dash pattern (include the
  1201. % trailing space).
  1202. %    \begin{macrocode}
  1203. \def\psset@dash#1{%
  1204.   \pst@expandafter\psset@@dash{#1} * * *\@nil
  1205.   \edef\psk@dash{\pst@number\pst@dimg \pst@number\pst@dimh}}
  1206. \def\psset@@dash#1 #2 #3\@nil{%
  1207.   \pssetlength\pst@dimg{#1}%
  1208.   \pssetlength\pst@dimh{#2}}
  1209. \psset@dash{5pt 3pt}
  1210. %    \end{macrocode}
  1211. % \end{macro}
  1212. % \begin{macro}{\psls@dashed}
  1213. %    \begin{macrocode}
  1214. \def\psls@dashed{\psk@dash \pst@linetype\space \tx@DashLine}
  1215. %    \end{macrocode}
  1216. % \end{macro}
  1217. % \begin{macro}{\tx@DashLine}
  1218. % Syntax:
  1219. % \begin{Ex}
  1220. %   <dim1 dim2 linetype> "DashLine"
  1221. % \end{Ex}
  1222. % "DashLine" adjusts, and then sets, the dash pattern "[<dim1 dim2>]" so that
  1223. % it fits evenly onto a path.
  1224. %    \begin{macrocode}
  1225. \pst@def{DashLine}<%
  1226.   % "a" is set to the length of first and last black segment, as fraction of
  1227.   % usual black segment.
  1228.   dup 0 gt
  1229.   { /a .5 def \tx@PathLength exch div }
  1230.   { pop /a 1 def \tx@PathLength }
  1231.   ifelse
  1232.   /b ED             % Pattern should fit evenly in b
  1233.   /x ED             % Length of white segment.
  1234.   /y ED             % Length of black segment.
  1235.   /z y x add def    % Total length of dash pattern.
  1236.   % If pattern  is repeated n times, total length is (nz + 2(a-.5)y).
  1237.   % Set length to b, solve for n, round, and leave on stack:
  1238.   %   n = round((b - 2(a-.5)y)/z)
  1239.   b a .5 sub 2 mul y mul sub z \tx@Div round
  1240.   % Adjust x and y by factor k so that
  1241.   %   (n(kz) + 2(a-.5)(ky)) = b.
  1242.   % Solve for k and leave two copies on stack:
  1243.   %   k = b/(nz + 2(a-.5)y)
  1244.   z mul a .5 sub 2 mul y mul add b exch \tx@Div dup
  1245.   % Scale x and y, set dash, and stroke:
  1246.   y mul /y ED x mul /x ED
  1247.   % Make sure both x and y aren't zero:
  1248.   x 0 eq y 0 eq and { /x 1 def /y 1 def } if
  1249.   [ y x ] 1 a sub y mul setdash stroke>
  1250. %    \end{macrocode}
  1251. % \end{macro}
  1252. % \begin{macro}{dotsep}
  1253. %    \begin{macrocode}
  1254. \def\psset@dotsep#1{\pst@getlength{#1}\psk@dotsep}
  1255. \psset@dotsep{3pt}
  1256. %    \end{macrocode}
  1257. % \end{macro}
  1258. % \begin{macro}{\psls@dotted}
  1259. %    \begin{macrocode}
  1260. \def\psls@dotted{\psk@dotsep \pst@linetype\space \tx@DotLine}%
  1261. %    \end{macrocode}
  1262. % \end{macro}
  1263. % \begin{macro}{\tx@DotLine}
  1264. % Syntax:
  1265. % \begin{Ex}
  1266. %   <dim linetype> "DotLine"
  1267. % \end{Ex}
  1268. % "DotLine" adjusts, and then sets, the dash pattern to produce a dotted line
  1269. % with distance <dim> between dots so that it fits evenly onto a path. Dots
  1270. % are produced by setting dash pattern with length of white segment equal to
  1271. % distance from center of dot to center of dot, length of black segment equal
  1272. % to 0, and "linecap" equal to 1.
  1273. %    \begin{macrocode}
  1274. \pst@def{DotLine}<%
  1275.   /b \tx@PathLength def  % Path length.
  1276.   /a ED                  % \pst@linetype.
  1277.   /z ED                  % dotsep.
  1278.   /y CLW def             % linewidth (dot diameter).
  1279.   /z y z add def         % Total length of dash pattern.
  1280.   % Set b to adjusted path length that pattern should be multiple of:
  1281.   a 0 gt
  1282.     % If closed, as many dots as spaces.
  1283.     { /b b a div def }
  1284.     { a 0 eq
  1285.         % If open with no arrows, one more dot than space.
  1286.         { /b b y sub def }
  1287.         % If open one arrow, as many dots as spaces (do nothing)
  1288.         % If open two arrows, one more space than dot.
  1289.         { a -3 eq { /b b y add def } if }
  1290.       ifelse }
  1291.   ifelse
  1292.   % Let n be number of times pattern is repeated:
  1293.   %  n = round(b/z)
  1294.   % Adjust length of pattern so that it fits evenly in b:
  1295.   %  z = b/n = b/(round(b/z))
  1296.   % z is length of white segment. Length of black segment is 0.
  1297.   [ 0 b b z \tx@Div round \tx@Div dup 0 le { pop 1 } if ]
  1298.   a 0 gt                % setting dash pattern.
  1299.     % Set offset to 0 if path is closed]
  1300.     { 0 }
  1301.     % Set offset to -(y/2) if open curve begins with arrow, (y/2) otherwise:
  1302.     { y 2 div a -2 gt { neg } if }
  1303.   ifelse
  1304.   % Setting linecap to 1 produces the dots.
  1305.   setdash 1 setlinecap stroke>
  1306. %    \end{macrocode}
  1307. % \end{macro}
  1308. % \begin{macro}{\psset@linestyle}
  1309. %    \begin{macrocode}
  1310. \def\psset@linestyle#1{%
  1311.   \@ifundefined{psls@#1}%
  1312.     {\@pstrickserr{Line style `#1' not defined}\@eha}%
  1313.     {\edef\pslinestyle{#1}}}
  1314. \psset@linestyle{solid}
  1315. %    \end{macrocode}
  1316. % \end{macro}
  1317. % \section{Fill styles\label{Fillstyles}}
  1318. % For each "fillstyle" <style>, the command "\psfs@<style>" should be the
  1319. % PostScript code that fills the region. The style should not assume anything
  1320. % about the PostScript environment's "linewidth" or color.
  1321. % \begin{macro}{\psfs@none}
  1322. %    \begin{macrocode}
  1323. \def\psfs@none{}
  1324. %    \end{macrocode}
  1325. % \end{macro}
  1326. % \begin{macro}{\psset@fillcolor,\psfillcolor}
  1327. %    \begin{macrocode}
  1328. \def\psset@fillcolor#1{\pst@getcolor{#1}\psfillcolor}
  1329. \psset@fillcolor{white}
  1330. %    \end{macrocode}
  1331. % \end{macro}
  1332. % \begin{macro}{\psfs@solid}
  1333. %    \begin{macrocode}
  1334. \def\psfs@solid{\pst@usecolor\psfillcolor fill }
  1335. %    \end{macrocode}
  1336. % \end{macro}
  1337. % \begin{macro}{hatchwidth}
  1338. %    \begin{macrocode}
  1339. \def\psset@hatchwidth#1{\pst@getlength{#1}\psk@hatchwidth}
  1340. \psset@hatchwidth{.8pt}
  1341. %    \end{macrocode}
  1342. % \end{macro}
  1343. % \begin{macro}{hatchsep}
  1344. %    \begin{macrocode}
  1345. \def\psset@hatchsep#1{\pst@getlength{#1}\psk@hatchsep}
  1346. \psset@hatchsep{4pt}
  1347. %    \end{macrocode}
  1348. % \end{macro}
  1349. % \begin{macro}{hatchcolor}
  1350. %    \begin{macrocode}
  1351. \def\psset@hatchcolor#1{\pst@getcolor{#1}\pshatchcolor}
  1352. \psset@hatchcolor{black}
  1353. %    \end{macrocode}
  1354. % \end{macro}
  1355. % \begin{macro}{hatchangle}
  1356. %    \begin{macrocode}
  1357. \def\psset@hatchangle#1{\pst@getangle{#1}\psk@hatchangle}
  1358. \psset@hatchangle{45}
  1359. %    \end{macrocode}
  1360. % \end{macro}
  1361. % \begin{macro}{\psfs@hlines}
  1362. %    \begin{macrocode}
  1363. \def\psfs@hlines{%
  1364.   \psk@hatchangle rotate
  1365.   \psk@hatchwidth SLW
  1366.   \pst@usecolor\pshatchcolor
  1367.   \psk@hatchsep \tx@LineFill}
  1368. \@namedef{psfs@hlines*}{gsave \psfs@solid grestore \psfs@hlines}
  1369. %    \end{macrocode}
  1370. % \end{macro}
  1371. % \begin{macro}{\tx@LineFill}
  1372. %    \begin{macrocode}
  1373. \pst@def{LineFill}<%
  1374.   abs CLW add /a ED              % hatchsep
  1375.   gsave
  1376.     clip
  1377.     pathbbox                   %leave llx,lly,urx,ury on stack
  1378.     a \tx@Div ceiling /y2 ED   % Number of top line to be drawn.
  1379.     /x2 ED
  1380.     a \tx@Div floor /y1 ED     % Number of bottom line to be drawn
  1381.     /x1 ED
  1382.     /n y2 y1 sub 1 add cvi def % Number of lines.
  1383.     /y1 a y1 mul def           % y-coordinate of bottom line.
  1384.     newpath 2 setlinecap
  1385.     n
  1386.     { currentstrokeadjust ==
  1387.       x1 y1 moveto
  1388.       x2 y1 L
  1389.       stroke
  1390.       /y1 y1 a add def }
  1391.     repeat
  1392.   grestore>
  1393. \pst@def{LineFill}<%
  1394.   abs CLW add /a ED              % hatchsep
  1395.   gsave
  1396.     clip
  1397.     pathbbox                   %leave llx,lly,urx,ury on stack
  1398.     a \tx@Div ceiling /y2 ED   % Number of top line to be drawn.
  1399.     /x2 ED
  1400.     a \tx@Div floor /y1 ED     % Number of bottom line to be drawn
  1401.     /x1 ED
  1402.     /n y2 y1 sub 1 add cvi def % Number of lines.
  1403.     /y1 a y1 mul def           % y-coordinate of bottom line.
  1404.     newpath 2 setlinecap
  1405.     systemdict /currentstrokeadjust known  % Level 2
  1406.     { currentstrokeadjust }
  1407.     { false }
  1408.     ifelse
  1409.     { /t { } def }
  1410.     { /t {
  1411.         transform
  1412.         0.25 sub round 0.25 add exch
  1413.         0.25 sub round 0.25 add exch
  1414.         itransform
  1415.       } bind def }
  1416.     ifelse
  1417.     n {
  1418.       x1 y1 t moveto
  1419.       x2 y1 t L
  1420.       stroke
  1421.       /y1 y1 a add def
  1422.     } repeat
  1423.   grestore>
  1424. %    \end{macrocode}
  1425. % \end{macro}
  1426. % \begin{macro}{\psfs@vlines}
  1427. %    \begin{macrocode}
  1428. \def\psfs@vlines{%
  1429.   90 rotate
  1430.   \psfs@hlines}
  1431. \@namedef{psfs@vlines*}{gsave \psfs@solid grestore \psfs@vlines}
  1432. %    \end{macrocode}
  1433. % \end{macro}
  1434. % \begin{macro}{\psfs@crosshatch}
  1435. %    \begin{macrocode}
  1436. \def\psfs@crosshatch{gsave \psfs@hlines grestore \psfs@vlines}
  1437. \@namedef{psfs@crosshatch*}{%
  1438.   gsave \psfs@solid grestore
  1439.   gsave \psfs@hlines grestore
  1440.   \psfs@vlines}
  1441. %    \end{macrocode}
  1442. % \end{macro}
  1443. % \begin{macro}{fillstyle}
  1444. %    \begin{macrocode}
  1445. \def\psset@fillstyle#1{%
  1446.   \@ifundefined{psfs@#1}%
  1447.     {\@pstrickserr{Undefined fill style: `#1'}\@eha}%
  1448.     {\edef\psfillstyle{#1}}}
  1449. \psset@fillstyle{none}
  1450. %    \end{macrocode}
  1451. % \end{macro}
  1452. % \section{Arrowheads and t-bars\label{Arrowheads}}
  1453. % It would be nice to use a font, with hinting.
  1454. % \begin{macro}{\psset@arrows,\psk@arrowA,\psk@arrowB}
  1455. % "\if@pst" is used as a flag for errors.
  1456. %    \begin{macrocode}
  1457. \def\psset@arrows#1{%
  1458.   \begingroup
  1459.     \pst@activearrows
  1460.     \xdef\pst@tempg{#1}%
  1461.   \endgroup
  1462.   \expandafter\psset@@arrows\pst@tempg\@empty-\@empty\@nil
  1463.   \if@pst\else
  1464.     \@pstrickserr{Bad arrows specification: #1}\@ehpa
  1465.   \fi}
  1466. \def\psset@@arrows#1-#2\@empty#3\@nil{%
  1467.   \@psttrue
  1468.   \def\next##1,#1-##2,##3\@nil{\def\pst@tempg{##2}}%
  1469.   \expandafter\next\pst@arrowtable,#1-#1,\@nil
  1470.   \@ifundefined{psas@\pst@tempg}%
  1471.     {\@pstfalse\def\psk@arrowA{}}%
  1472.     {\let\psk@arrowA\pst@tempg}%
  1473.   \@ifundefined{psas@#2}%
  1474.     {\@pstfalse\def\psk@arrowB{}}%
  1475.     {\def\psk@arrowB{#2}}}
  1476. \def\psk@arrowA{}
  1477. \def\psk@arrowB{}
  1478. %    \end{macrocode}
  1479. % \end{macro}
  1480. % \begin{macro}{\pst@arrowtable}
  1481. % This is a translator for "arrowA". Add to it with "\edef", as in
  1482. % \begin{LVerbatim}
  1483. %   \edef\pst@arrowtable{\pst@arrowtable,*o-o*}
  1484. % \end{LVerbatim}
  1485. %    \begin{macrocode}
  1486. \def\pst@arrowtable{,<->,<<->>,>-<,>>-<<,(-),[-]}
  1487. %    \end{macrocode}
  1488. % \end{macro}
  1489. % \begin{macro}{\pst@activearrows}
  1490. % This redefines certain characters in case they are active, before expanding
  1491. % the "arrows" argument. Add to it with "\expandafter", as in
  1492. % \begin{LVerbatim}
  1493. %   \begingroup
  1494. %     \catcode`\:=13
  1495. %     \expandafter\gdef\expandafter\pst@activearrows
  1496. %       \expandafter{\def:{\string:}}
  1497. %   \endgroup
  1498. % \end{LVerbatim}
  1499. %    \begin{macrocode}
  1500. \begingroup
  1501.   \catcode`\<=13
  1502.   \catcode`\>=13
  1503.   \catcode`\|=13
  1504.   \gdef\pst@activearrows{\def<{\string<}\def>{\string>}\def|{\string|}}
  1505. \endgroup
  1506. %    \end{macrocode}
  1507. % \end{macro}
  1508. % \begin{macro}{BeginArrow,EndArrow}
  1509. % For each arrow <arrow>, "\psas@<arrow>" should be PostScript code so that
  1510. % \begin{LVerbatim}
  1511. %   <y2 x2 y1 x1> BeginArrow \psk@arrowscale \psas@<arrow> EndArrow
  1512. % \end{LVerbatim}
  1513. % \begin{itemize}
  1514. %  \item Draws an arrow with the tip at <x1 y1>, and
  1515. % \item Leaves on the stack <y2 x2 x1' y1'>, where <x1' y1'> is the position
  1516. % that a connecting line should start from.
  1517. % \end{itemize}
  1518. % "BeginArrow" sets up an environment so that "\psas@<arrow>" only has to draw
  1519. % an arrow pointing down and with the tip at "0 0" and , and leave the current
  1520. % point where a connecting line should start from. "EndArrow" then restores
  1521. % the original environment and translates the current point into the original
  1522. % coordinate system.
  1523. % A special dictionary "ADict" is used with arrows so that scratch variables
  1524. % will not conflict. The matrix is saved as "@mtrx" to indicate that the arrow
  1525. % procedures should not change this. The same is true for "@x1", "@y1", "@x2",
  1526. % "@y2" and "@angle", which are used by a patch of "BeginArrow" and "EndArrow"
  1527. % that is required for some versions of Sun's NewsPrint (see "read-me.pst").
  1528. %    \begin{macrocode}
  1529. \pst@def{BeginArrow}<%
  1530.   ADict begin
  1531.   /@mtrx CM def
  1532.   gsave
  1533.     2 copy T
  1534.     2 index sub neg exch 3 index sub exch \tx@Atan
  1535.     rotate
  1536.     newpath>
  1537. \pst@def{EndArrow}<@mtrx setmatrix CP grestore end>
  1538. %    \end{macrocode}
  1539. % \end{macro}
  1540. % \begin{macro}{arrowscale}
  1541. %    \begin{macrocode}
  1542. \def\psset@arrowscale#1{\pst@getscale{#1}\psk@arrowscale}
  1543. \psset@arrowscale{1}
  1544. %    \end{macrocode}
  1545. % \end{macro}
  1546. % \begin{macro}{\psset@arrowsize,\psk@arrowsize}
  1547. %    \begin{macrocode}
  1548. \def\psset@arrowsize#1{%
  1549.   \pst@expandafter\pst@getdimnum{#1} {} {} {}\@nil
  1550.   \edef\psk@arrowsize{\pst@number\pst@dimg \pst@tempg}}
  1551. \psset@arrowsize{2pt 3}
  1552. %    \end{macrocode}
  1553. % \end{macro}
  1554. % \begin{macro}{\psset@arrowlength,\psk@arrowlength}
  1555. %    \begin{macrocode}
  1556. \def\psset@arrowlength#1{\pst@checknum{#1}\psk@arrowlength}
  1557. \psset@arrowlength{1.4}
  1558. %    \end{macrocode}
  1559. % \end{macro}
  1560. % \begin{macro}{\psset@arrowinset,\psk@arrowinset}
  1561. %    \begin{macrocode}
  1562. \def\psset@arrowinset#1{\pst@checknum{#1}\psk@arrowinset}%
  1563. \psset@arrowinset{.4}
  1564. %    \end{macrocode}
  1565. % \end{macro}
  1566. % \begin{macro}{\tx@Arrow}
  1567. % Syntax:
  1568. % \begin{LVerbatim}
  1569. %   <boolean> \psk@arrowinset \psk@arrowlength \psk@arrowsize Arrow
  1570. % \end{LVerbatim}
  1571. % <boolean> is "true" for reverse arrows and "false" for normal arrows.
  1572. %    \begin{macrocode}
  1573. \pst@def{Arrow}<%
  1574.   CLW mul add dup               % width
  1575.   2 div /w ED                   % Half width
  1576.   mul dup /h ED                 % Height
  1577.   mul /a ED                     % Inset
  1578.   { 0 h T 1 -1 scale } if   % For reverse arrows
  1579.   w neg h moveto
  1580.   0 0 L
  1581.   w h L
  1582.   w neg a neg rlineto
  1583.   gsave fill grestore>
  1584. %    \end{macrocode}
  1585. % \end{macro}
  1586. % \begin{macro}{\psas@>}
  1587. %    \begin{macrocode}
  1588. \@namedef{psas@>}{%
  1589.   false \psk@arrowinset \psk@arrowlength \psk@arrowsize \tx@Arrow}
  1590. %    \end{macrocode}
  1591. % \end{macro}
  1592. % \begin{macro}{\psas@>>}
  1593. %    \begin{macrocode}
  1594. \@namedef{psas@>>}{%
  1595.   false \psk@arrowinset \psk@arrowlength \psk@arrowsize \tx@Arrow
  1596.   0 h T
  1597.   gsave
  1598.     newpath
  1599.     false \psk@arrowinset \psk@arrowlength \psk@arrowsize \tx@Arrow
  1600.     CP
  1601.   grestore
  1602.   CP newpath moveto
  1603.   2 copy
  1604.   stroke
  1605.   moveto}
  1606. %    \end{macrocode}
  1607. % \end{macro}
  1608. % \begingroup
  1609. % \catcode`\<=12
  1610. % \begin{macro}{\psas@<}
  1611. %    \begin{macrocode}
  1612. \@namedef{psas@<}{%
  1613.   true \psk@arrowinset \psk@arrowlength \psk@arrowsize \tx@Arrow}
  1614. %    \end{macrocode}
  1615. % \end{macro}
  1616. % \begin{macro}{\psas@<<}
  1617. %    \begin{macrocode}
  1618. \@namedef{psas@<<}{%
  1619.   true \psk@arrowinset \psk@arrowlength \psk@arrowsize \tx@Arrow
  1620.   CP newpath moveto 0 a neg L stroke 0 h neg T
  1621.   false \psk@arrowinset \psk@arrowlength \psk@arrowsize \tx@Arrow}
  1622. %    \end{macrocode}
  1623. % \end{macro}
  1624. % \endgroup
  1625. % \begin{macro}{\psset@tbarsize,\psk@tbarsize}
  1626. %    \begin{macrocode}
  1627. \def\psset@tbarsize#1{%
  1628.   \pst@expandafter\pst@getdimnum{#1} {} {} {}\@nil
  1629.   \edef\psk@tbarsize{\pst@number\pst@dimg \pst@tempg}}
  1630. \psset@tbarsize{2pt 5}
  1631. %    \end{macrocode}
  1632. % \end{macro}
  1633. % \begin{macro}{Tbar}
  1634. % Syntax
  1635. % \begin{LVerbatim}
  1636. %   \psk@tbarsize Tbar
  1637. % \end{LVerbatim}
  1638. %    \begin{macrocode}
  1639. \pst@def{Tbar}<%
  1640.   CLW mul add /z ED              % width
  1641.   z -2 div CLW 2 div moveto
  1642.   z 0 rlineto
  1643.   stroke
  1644.   0 CLW moveto>
  1645. %    \end{macrocode}
  1646. % \end{macro}
  1647. % \begin{macro}{\psas@|}
  1648. %    \begin{macrocode}
  1649. \@namedef{psas@|}{\psk@tbarsize \tx@Tbar}
  1650. %    \end{macrocode}
  1651. % \end{macro}
  1652. % \begin{macro}{\psas@|*}
  1653. %    \begin{macrocode}
  1654. \@namedef{psas@|*}{0 CLW -2 div T \psk@tbarsize \tx@Tbar}
  1655. %    \end{macrocode}
  1656. % \end{macro}
  1657. % \begin{macro}{\psset@bracketlength,\psk@bracketlength}
  1658. %    \begin{macrocode}
  1659. \def\psset@bracketlength#1{\pst@checknum{#1}\psk@bracketlength}
  1660. \psset@bracketlength{.15}
  1661. %    \end{macrocode}
  1662. % \end{macro}
  1663. % \begin{macro}{\tx@Bracket,\tx@@Bracket}
  1664. % Syntax
  1665. % \begin{LVerbatim}
  1666. %   \psk@bracketlength \psk@tbarsize Bracket
  1667. % \end{LVerbatim}
  1668. %    \begin{macrocode}
  1669. \pst@def{Bracket}<%
  1670.   CLW mul add dup
  1671.   CLW sub 2 div /x ED   % adjusted half width
  1672.   mul CLW add /y ED     % y-position of height
  1673.   /z CLW 2 div def
  1674.   x neg y moveto
  1675.   x neg CLW 2 div L
  1676.   x CLW 2 div L
  1677.   x y L
  1678.   stroke
  1679.   0 CLW moveto>
  1680. %    \end{macrocode}
  1681. % \end{macro}
  1682. % \begin{macro}{\psas@]}
  1683. %    \begin{macrocode}
  1684. \@namedef{psas@]}{\psk@bracketlength \psk@tbarsize \tx@Bracket}
  1685. %    \end{macrocode}
  1686. % \end{macro}
  1687. % \begin{macro}{\psset@rbracketlength,\psk@rbracketlength}
  1688. %    \begin{macrocode}
  1689. \def\psset@rbracketlength#1{\pst@checknum{#1}\psk@rbracketlength}
  1690. \psset@rbracketlength{.15}
  1691. %    \end{macrocode}
  1692. % \end{macro}
  1693. % \begin{macro}{RoundBracket}
  1694. % Syntax
  1695. % \begin{LVerbatim}
  1696. %   \psk@bracketlength \psk@tbarsize RoundBracket
  1697. % \end{LVerbatim}
  1698. %    \begin{macrocode}
  1699. \pst@def{RoundBracket}<%
  1700.   CLW mul add dup
  1701.   2 div /x ED           % half width
  1702.   mul /y ED             % height
  1703.   /mtrx CM def
  1704.   0 CLW 2 div T
  1705.   x y mul 0 ne { x y scale } if
  1706.   1 1 moveto
  1707.    .85 .5   .35  0   0 0 curveto
  1708.   -.35  0  -.85 .5  -1 1 curveto
  1709.   mtrx setmatrix
  1710.   stroke
  1711.   0 CLW moveto>
  1712. %    \end{macrocode}
  1713. % \end{macro}
  1714. % \begin{macro}{\psas@(}
  1715. %    \begin{macrocode}
  1716. \@namedef{psas@)}{\psk@rbracketlength \psk@tbarsize \tx@RoundBracket}
  1717. %    \end{macrocode}
  1718. % \end{macro}
  1719. % \begin{macro}{\psas@c,\psas@cc,\psas@C}
  1720. % This is not going to be used frequently, and so we don't bother defining a
  1721. % PostScript procedure in the header.
  1722. %    \begin{macrocode}
  1723. \def\psas@c{1 \psas@@c}
  1724. \def\psas@cc{0 CLW 2 div T 1 \psas@@c}
  1725. \def\psas@C{2 \psas@@c}
  1726. \def\psas@@c{%
  1727.   setlinecap
  1728.   0 0 moveto
  1729.   0 CLW 2 div L
  1730.   stroke
  1731.   0 0 moveto}
  1732. %    \end{macrocode}
  1733. % \end{macro}
  1734. % \begin{macro}{\psas@}
  1735. %    \begin{macrocode}
  1736. \def\psas@{}
  1737. \psset@arrows{-}
  1738. %    \end{macrocode}
  1739. % \end{macro}
  1740. % \section{Graphics objects: processing arguments}
  1741. % \begin{macro}{\pst@par,\addto@par,\use@par}
  1742. % Graphics objects accumulate <parameter>=<value> pairs in the command
  1743. % sequence "\pst@par". They use "\addto@par" to add to "\pst@par", and
  1744. % "\use@par" to make the parameter changes effective.
  1745. %    \begin{macrocode}
  1746. \def\pst@par{}
  1747. \def\addto@par#1{%
  1748.   \ifx\pst@par\@empty
  1749.     \def\pst@par{#1}%
  1750.   \else
  1751.     \expandafter\def\expandafter\pst@par\expandafter{\pst@par,#1}%
  1752.   \fi}
  1753. \def\use@par{%
  1754.   \ifx\pst@par\@empty\else
  1755.     \expandafter\@psset\pst@par,\@nil
  1756.     \def\pst@par{}%
  1757.   \fi}
  1758. %    \end{macrocode}
  1759. % \end{macro}
  1760. % \begin{macro}{\pst@object}
  1761. % Any macro, such as "\psline", that uses graphics parameters should begin as
  1762. % follows:
  1763. % \begin{LVerbatim}
  1764. %   \def\psline{\def\pst@par{}\pst@object{psline}}
  1765. %   \def\psline@i{ ... }
  1766. % \end{LVerbatim}
  1767. % "\pst@object" checkes for the optional "[<par>=<value>,...]" argument, adds
  1768. % key-value pairs to "\pst@par" if found, skips spaces, and then invokes
  1769. % "\psline@i".
  1770. %    \begin{macrocode}
  1771. \def\pst@object#1{%
  1772.   \pst@ifstar{\@ifnextchar[{\pst@@object{#1}}{\@nameuse{#1@i}}}}
  1773. \def\pst@@object#1[#2]{%
  1774.   \addto@par{#2}\@ifnextchar+{\@nameuse{#1@i}}{\@nameuse{#1@i}}}
  1775. %    \end{macrocode}
  1776. % \end{macro}
  1777. % \begin{macro}{\newpsobject}
  1778. % For example,
  1779. % \begin{LVerbatim}
  1780. %   \newpsobject{dottedline}{psline}{linestyle=dotted}
  1781. % \end{LVerbatim}
  1782. % has the following effect:
  1783. % \begin{LVerbatim}
  1784. %   \def\dottedline{%
  1785. %     \def\pst@par{linestyle=dotted}\pst@object{psline}}
  1786. % \end{LVerbatim}
  1787. % and thus "\dottedline" is just like "\psline", except that the default falue
  1788. % of "linestyle" is changed to "dotted".
  1789. %    \begin{macrocode}
  1790. \def\newpsobject#1#2#3{%
  1791.   \@ifundefined{#2@i}%
  1792.     {\@pstrickserr{Graphics object `#2' not defined}\@eha}%
  1793.     {\@namedef{#1}{\def\pst@par{#3}\pst@object{#2}}}\ignorespaces}
  1794. %    \end{macrocode}
  1795. % \end{macro}
  1796. % \begin{macro}{\pst@getarrows}
  1797. % "\pst@getarrows{foo}" checks for an optional argument containing arrows, and
  1798. % then invokes "foo". The arrows argument must be followed by "(".
  1799. %    \begin{macrocode}
  1800. \def\pst@getarrows#1{\@ifnextchar({#1}{\pst@@getarrows{#1}}}
  1801. \def\pst@@getarrows#1#2{\addto@par{arrows=#2}#1}
  1802. %    \end{macrocode}
  1803. % \end{macro}
  1804. % \section{Graphics objects: Basics \TeX\ macros\label{Objects}}
  1805. % Each graphics object should use one of the following:
  1806. % \begin{center}
  1807. % \begin{tabular}{ll}
  1808. % "\begin@OpenObj ... \end@OpenObj" & Open curves with arrows.\\
  1809. % "\begin@AltOpenObj ... \end@AltOpenObj" & Open curves w/o arrows.\\
  1810. % "\begin@ClosedObj ... \end@ClosedObj" & Closed curves.\\
  1811. % "\begin@SpecialObj ... \end@SpecialObj" & Other.
  1812. % \end{tabular}
  1813. % \end{center}
  1814. % This makes it possible for "\pscustom" to work by redefining these.
  1815. % \begin{macro}{\begin@ClosedObj,\end@ClosedObj}
  1816. %    \begin{macrocode}
  1817. \def\begin@ClosedObj{%
  1818.   \leavevmode
  1819.   \pst@killglue
  1820.   \begingroup
  1821.     \use@par
  1822.     \solid@star
  1823.     \ifpsdoubleline \pst@setdoublesep \fi
  1824.     \init@pscode}
  1825. \def\end@ClosedObj{%
  1826.     \ifpsshadow \pst@closedshadow \fi
  1827.     \ifdim\psk@border\p@>\z@ \pst@addborder \fi
  1828.     \pst@fill
  1829.     \pst@stroke
  1830.     \ifpsdoubleline \pst@doublestroke \fi
  1831.     \ifshowpoints
  1832.       \addto@pscode{Points aload length 2 div cvi /N ED \psdots@iii}%
  1833.     \fi
  1834.     \use@pscode
  1835.   \endgroup
  1836.   \ignorespaces}
  1837. %    \end{macrocode}
  1838. % \end{macro}
  1839. % \begin{macro}{\begin@OpenObj,\begin@AltOpenObj,\end@OpenObj}
  1840. %    \begin{macrocode}
  1841. \def\begin@OpenObj{%
  1842.   \begin@ClosedObj
  1843.     \let\pst@linetype\pst@arrowtype
  1844.     \pst@addarrowdef}
  1845. \def\begin@AltOpenObj{%
  1846.   \begin@ClosedObj
  1847.     \def\pst@repeatarrowsflag{\z@}%
  1848.     \def\pst@linetype{0}}
  1849. \def\end@OpenObj{%
  1850.     \ifpsshadow \pst@openshadow \fi
  1851.     \ifdim\psk@border\p@>\z@ \pst@addborder \fi
  1852.     \pst@fill
  1853.     \pst@stroke
  1854.     \ifpsdoubleline \pst@doublestroke \fi
  1855.     \ifnum\pst@repeatarrowsflag>\z@ \pst@repeatarrows \fi
  1856.     \ifshowpoints \pst@OpenShowPoints \fi
  1857.     \use@pscode
  1858.   \endgroup
  1859.   \ignorespaces}
  1860. %    \end{macrocode}
  1861. % \end{macro}
  1862. % \begin{macro}{\begin@SpecialObj,\end@SpecialObj}
  1863. %    \begin{macrocode}
  1864. \def\begin@SpecialObj{%
  1865.   \leavevmode
  1866.   \pst@killglue
  1867.   \begingroup
  1868.     \use@par
  1869.     \init@pscode}
  1870. \def\end@SpecialObj{%
  1871.     \use@pscode
  1872.   \endgroup
  1873.   \ignorespaces}
  1874. %    \end{macrocode}
  1875. % \end{macro}
  1876. % \begin{macro}{\init@pscode,\addto@pscode,\use@pscode}
  1877. % Graphics objects are built up by adding PostScript code to "\pst@code" with
  1878. % "\addto@pscode". "\use@pscode" then adds leading and trailing PostScript
  1879. % code, and (normally) inserts it in a "\special" (it also most empty
  1880. % "\pst@code"). Hacks like "\psclip", "\multips" and "\pstextpath" work by
  1881. % redefining "\use@pscode". These hacks use "\use@pscode" themselves when
  1882. % appropriate, making limited nesting of these hacks is possible. "\PSTtoEPS"
  1883. % works be redefining "\addto@pscode" so that it writes to a file. All this
  1884. % was carefully designed so that these hacks would work. Watch out!
  1885. %    \begin{macrocode}
  1886. \def\pst@code{}%
  1887. \def\init@pscode{%
  1888.   \addto@pscode{%
  1889.     \pst@number\pslinewidth SLW
  1890.     \pst@usecolor\pslinecolor}}
  1891. \def\addto@pscode#1{\xdef\pst@code{\pst@code#1\space}}
  1892. \def\use@pscode{%
  1893.   \pstverb{%
  1894.     \pst@dict
  1895.       \tx@STP
  1896.       newpath
  1897.       \psk@origin
  1898.       \psk@swapaxes
  1899.       \pst@code
  1900.      end}%
  1901.    \gdef\pst@code{}}
  1902. %    \end{macrocode}
  1903. % \end{macro}
  1904. % \begin{macro}{\pst@killglue}
  1905. %    \begin{macrocode}
  1906. \def\KillGlue{%
  1907.   \def\pst@killglue{\unskip\ifdim\lastskip>\z@\expandafter\pst@killglue\fi}}
  1908. \def\DontKillGlue{\let\pst@killglue\relax}
  1909. \DontKillGlue
  1910. %    \end{macrocode}
  1911. % \end{macro}
  1912. % \begin{macro}{\solid@star}
  1913. % The optional "*" is typically used to make a solid option. This means that
  1914. % "linestyle" is set to "none", "linewidth" is set to "0", and "fillcolor" is
  1915. % set to "linecolor".
  1916. %    \begin{macrocode}
  1917. \def\solid@star{%
  1918.   \if@star
  1919.     \pslinewidth=\z@
  1920.     \psdoublelinefalse
  1921.     \def\pslinestyle{none}%
  1922.     \def\psfillstyle{solid}%
  1923.     \let\psfillcolor\pslinecolor
  1924.   \fi}
  1925. %    \end{macrocode}
  1926. % \end{macro}
  1927. % \begin{macro}{\pst@setdoublesep}
  1928. %    \begin{macrocode}
  1929. \def\pst@setdoublesep{%
  1930.   \pst@getlength\psdoublesep\psdoublesep
  1931.   \pslinewidth=2\pslinewidth
  1932.   \advance\pslinewidth\psdoublesep\p@
  1933.   \let\pst@setdoublesep\relax}
  1934. %    \end{macrocode}
  1935. % \end{macro}
  1936. % \begin{macro}{\tx@Shadow}
  1937. % Syntax:
  1938. % \begin{Ex}
  1939. %    <x y> Shadow
  1940. % \end{Ex}
  1941. % translates current path by <x y>.
  1942. %    \begin{macrocode}
  1943. \pst@def{Shadow}<%
  1944.     { /moveto load }
  1945.     { /lineto load }
  1946.     { /curveto load }
  1947.     { /closepath load }
  1948.     pathforall
  1949.   cvx
  1950.   newpath
  1951.   3 1 roll
  1952.   exec>
  1953. %    \end{macrocode}
  1954. % \end{macro}
  1955. % \begin{macro}{\pst@closedshadow}
  1956. %    \begin{macrocode}
  1957. \def\pst@closedshadow{%
  1958.   \addto@pscode{%
  1959.     gsave
  1960.     \psk@shadowsize \psk@shadowangle \tx@PtoC
  1961.     \tx@Shadow
  1962.     \pst@usecolor\psshadowcolor
  1963.     gsave fill grestore
  1964.     stroke
  1965.     grestore
  1966.     gsave
  1967.     \pst@usecolor\psfillcolor
  1968.     gsave fill grestore
  1969.     stroke
  1970.     grestore}}
  1971. %    \end{macrocode}
  1972. % \end{macro}
  1973. % \begin{macro}{\pst@openshadow}
  1974. %    \begin{macrocode}
  1975. \def\pst@openshadow{%
  1976.   \addto@pscode{%
  1977.     gsave
  1978.       \psk@shadowsize \psk@shadowangle \tx@PtoC
  1979.       \tx@Shadow
  1980.       \pst@usecolor\psshadowcolor
  1981.       \ifx\psfillstyle\@none\else
  1982.         gsave fill grestore
  1983.       \fi
  1984.       stroke}%
  1985.   \pst@repeatarrows
  1986.   \addto@pscode{grestore}
  1987.   \ifx\psfillstyle\@none\else
  1988.     \addto@pscode{%
  1989.       gsave
  1990.       \pst@usecolor\psfillcolor
  1991.       gsave fill grestore
  1992.       stroke
  1993.       grestore}
  1994.    \fi}
  1995. %    \end{macrocode}
  1996. % \end{macro}
  1997. % \begin{macro}{\pst@addborder}
  1998. %    \begin{macrocode}
  1999. \def\pst@addborder{%
  2000.   \addto@pscode{%
  2001.     gsave
  2002.       \psk@border 2 mul
  2003.       CLW add SLW
  2004.       \pst@usecolor\psbordercolor
  2005.       stroke
  2006.     grestore}}
  2007. %    \end{macrocode}
  2008. % \end{macro}
  2009. % \begin{macro}{\pst@stroke}
  2010. %    \begin{macrocode}
  2011. \def\pst@stroke{%
  2012.   \ifx\pslinestyle\@none\else
  2013.     \addto@pscode{%
  2014.       gsave
  2015.         \pst@number\pslinewidth SLW
  2016.         \pst@usecolor\pslinecolor
  2017.         \@nameuse{psls@\pslinestyle}
  2018.       grestore}%
  2019.   \fi}
  2020. %    \end{macrocode}
  2021. % \end{macro}
  2022. % \begin{macro}{\pst@fill}
  2023. %    \begin{macrocode}
  2024. \def\pst@fill{%
  2025.   \ifx\psfillstyle\@none\else
  2026.     \addto@pscode{gsave \@nameuse{psfs@\psfillstyle} grestore}%
  2027.   \fi}
  2028. %    \end{macrocode}
  2029. % \end{macro}
  2030. % \begin{macro}{\pst@doublestroke}
  2031. %    \begin{macrocode}
  2032. \def\pst@doublestroke{%
  2033.   \addto@pscode{%
  2034.     gsave
  2035.       \psdoublesep SLW
  2036.       \pst@usecolor\psdoublecolor
  2037.       stroke
  2038.     grestore}}
  2039. %    \end{macrocode}
  2040. % \end{macro}
  2041. % \begin{macro}{\pst@arrowtype}
  2042. %    \begin{macrocode}
  2043. \def\pst@arrowtype{%
  2044.   \ifx\psk@arrowB\@empty 0 \else -2 \fi
  2045.   \ifx\psk@arrowA\@empty 0 \else -1 \fi
  2046.   add}
  2047. %    \end{macrocode}
  2048. % \end{macro}
  2049. % \begin{macro}{\pst@addarrowdef,\pst@arrowdef,\pst@arrowtype}
  2050. % "ArrowA" takes two coordinates from the stack, draws the arrow with the tip
  2051. % at the top coordinate, leaves the second coordinate on the stack and leaves
  2052. % the current point where a line should join.
  2053. % "ArrowB" takes two coordinates from the stack, draws the arrow with the tip
  2054. % at the top coordinate, and leaves both coordinates on the stack, without
  2055. % changing the graphics state.
  2056. % This particular definition of "ArrowA" is important for "\pscustom".
  2057. % "ArrowA" and "ArrowB" might also save the arrow coordinates, because
  2058. % sometimes it is necessary to redraw the arrows (see
  2059. % "\pst@setrepeatarrowsflag").
  2060. %    \begin{macrocode}
  2061. \def\pst@addarrowdef{%
  2062.   \addto@pscode{%
  2063.     /ArrowA {
  2064.       \ifx\psk@arrowA\@empty
  2065.         \pst@oplineto
  2066.       \else
  2067.         \pst@arrowdef{A}
  2068.         moveto
  2069.       \fi
  2070.     } def
  2071.     /ArrowB {
  2072.       \ifx\psk@arrowB\@empty \else \pst@arrowdef{B} \fi
  2073.     } def}}
  2074. \def\pst@arrowdef#1{%
  2075.   \ifnum\pst@repeatarrowsflag>\z@
  2076.     /Arrow#1c [ 6 2 roll ] cvx def Arrow#1c
  2077.   \fi
  2078.   \tx@BeginArrow
  2079.   \psk@arrowscale
  2080.   \@nameuse{psas@\@nameuse{psk@arrow#1}}
  2081.   \tx@EndArrow}
  2082. %    \end{macrocode}
  2083. % \end{macro}
  2084. % \begin{macro}{\pst@repeatarrows}
  2085. %    \begin{macrocode}
  2086. \def\pst@repeatarrows{%
  2087.   \addto@pscode{%
  2088.     gsave
  2089.     \ifx\psk@arrowA\@empty\else
  2090.       ArrowAc ArrowA pop pop
  2091.     \fi
  2092.     \ifx\psk@arrowB\@empty\else
  2093.       ArrowBc ArrowB pop pop pop pop
  2094.     \fi
  2095.     grestore}}
  2096. %    \end{macrocode}
  2097. % \end{macro}
  2098. % \begin{macro}{\pst@OpenShowPoints}
  2099. %    \begin{macrocode}
  2100. \def\pst@OpenShowPoints{%
  2101.   \addto@pscode{%
  2102.     gsave
  2103.       \psk@dotsize
  2104.       \@nameuse{psds@\psk@dotstyle}
  2105.       /TheDot {
  2106.         gsave T \psk@dotangle \psk@dotscale Dot grestore
  2107.       } def
  2108.       newpath
  2109.       Points aload length 2 div 2 sub cvi /N ED
  2110.       N 0 ge
  2111.       { \ifx\psk@arrowA\@empty
  2112.           TheDot
  2113.         \else
  2114.           pop pop
  2115.         \fi
  2116.         N { TheDot } repeat
  2117.         \ifx\psk@arrowB\@empty
  2118.           TheDot
  2119.         \else
  2120.           pop pop
  2121.         \fi }
  2122.       { N 2 mul { pop } repeat }
  2123.       ifelse
  2124.     grestore}}
  2125. %    \end{macrocode}
  2126. % \end{macro}
  2127. % \section{Custom graphics}
  2128. % Graphics objects using "\begin@SpecialObj" cannot be used with "\pscustom".
  2129. % It is up to the other graphics objects to be compatible with "\pscustom".
  2130. % This means:
  2131. % \begin{itemize}
  2132. % \item To use the current point as an additional coordinate, when it exists,
  2133. % the graphics object should insert "\pst@cp".
  2134. % \item For graphics objects that use "\begin@OpenObj", the "ArrowA" is
  2135. % defined by "\pscustom" to connect the top coordinate with the current point
  2136. % by a line, if there is a current point. Other graphics objects should use
  2137. % "\pst@oplineto" as a substitute for "moveto" if they wish to connect a
  2138. % coordinate to the current point if it exists.
  2139. % \end{itemize}
  2140. % Closed graphics objects are not under an obligation to anything particularly
  2141. % sensible the current point exists.
  2142. % \begin{macro}{\pscustom}
  2143. % The main graphics object modifies "\begin@OpenObj" and "\end@OpenObj" so
  2144. % that the open curves extend the current path.
  2145. %    \begin{macrocode}
  2146. \def\pscustom{\def\pst@par{}\pst@object{pscustom}}
  2147. \long\def\pscustom@i#1{%
  2148.   \begin@SpecialObj
  2149.     \solid@star
  2150.     \let\pst@ifcustom\iftrue
  2151.     \let\begin@ClosedObj\begin@CustomObj
  2152.     \let\end@ClosedObj\endgroup
  2153.     \def\begin@OpenObj{\begin@CustomObj\pst@addarrowdef}%
  2154.     \let\end@OpenObj\endgroup
  2155.     \let\begin@AltOpenObj\begin@CustomObj
  2156.     \def\begin@SpecialObj{%
  2157.       \begingroup
  2158.       \pst@misplaced{special graphics object}%
  2159.       \def\addto@pscode####1{}
  2160.       \let\end@SpecialObj\endgroup}%
  2161.     \def\@multips(##1)(##2)##3##4{\pst@misplaced\multips}%
  2162.     \def\psclip##1{\pst@misplaced\psclip}%
  2163.     \def\pst@repeatarrowsflag{\z@}%
  2164.     \let\pst@setrepeatarrowsflag\relax
  2165.     \showpointsfalse
  2166.     \let\showpointstrue\relax
  2167.     \def\pst@linetype{\pslinetype}%
  2168.     \let\psset@liftpen\psset@@liftpen
  2169.     \psset@liftpen{\z@}%
  2170.     \def\pst@cp{/currentpoint load stopped pop }%
  2171.     \def\pst@oplineto{/lineto load stopped { moveto } if }%
  2172.     \def\pst@optcp##1##2{%
  2173.       \ifnum##1=\z@\def##2{/currentpoint load stopped { 0 0 } if }\fi}%
  2174.     \let\caddto@pscode\addto@pscode
  2175.     \def\cuse@par##1{{\use@par##1}}%
  2176.     \the\pst@customdefs
  2177.     \setbox\pst@hbox=\hbox{#1}%
  2178.     \pst@fill
  2179.     \pst@stroke
  2180.   \end@SpecialObj}
  2181. %    \end{macrocode}
  2182. % \end{macro}
  2183. % \begin{macro}{\begin@CustomObj,\end@CustomObj}
  2184. %    \begin{macrocode}
  2185. \def\begin@CustomObj{%
  2186.   \begingroup
  2187.     \use@par
  2188.     \addto@pscode{%
  2189.       \pst@number\pslinewidth SLW
  2190.       \pst@usecolor\pslinecolor}}
  2191. %    \end{macrocode}
  2192. % \end{macro}
  2193. % \begin{macro}{\psset@liftpen,\pst@cp,\pst@oplineto,\pst@optcp}
  2194. %    \begin{macrocode}
  2195. \def\pst@oplineto{moveto }
  2196. \def\pst@cp{}
  2197. \def\pst@optcp#1#2{}
  2198. \def\psset@liftpen#1{}
  2199. \def\psset@@liftpen#1{%
  2200.   \ifcase#1\relax
  2201.     \def\psk@liftpen{\z@}%
  2202.     \def\pst@cp{/currentpoint load stopped pop }%
  2203.     \def\pst@oplineto{/lineto load stopped { moveto } if }%
  2204.   \or
  2205.     \def\psk@liftpen{1}%
  2206.     \def\pst@cp{}%
  2207.     \def\pst@oplineto{/lineto load stopped { moveto } if }%
  2208.   \or
  2209.     \def\psk@liftpen{2}%
  2210.     \def\pst@cp{}%
  2211.     \def\pst@oplineto{moveto }%
  2212.   \fi}
  2213. \psset@liftpen{0}
  2214. \def\psk@liftpen{-1}
  2215. %    \end{macrocode}
  2216. % \end{macro}
  2217. % \begin{macro}{\psset@linetype,\pslinetype}
  2218. %    \begin{macrocode}
  2219. \def\psset@linetype#1{%
  2220.   \pst@getint{#1}\pslinetype
  2221.   \ifnum\pst@dimg<-3
  2222.     \@pstrickserr{linetype must be greater than -3}\@ehpa
  2223.     \def\pslinetype{0}%
  2224.   \fi}
  2225. \psset@linetype{0}
  2226. %    \end{macrocode}
  2227. % \end{macro}
  2228. % \begin{macro}{\caddto@pscode}
  2229. % Commands that should only occur in "\pscustom" should use this. Obsolete?
  2230. %    \begin{macrocode}
  2231. \def\caddto@pscode#1{%
  2232.   \@pstrickserr{Command can only be used in \string\pscustom}\@ehpa}
  2233. \let\cuse@par\caddto@pscode
  2234. %    \end{macrocode}
  2235. % \end{macro}
  2236. % \begin{macro}{\tx@MSave,\tx@MRestore}
  2237. % It doesn't seem worth adding these to the header file.
  2238. %    \begin{macrocode}
  2239. \def\tx@MSave{%
  2240.   /msavemtrx
  2241.   [ tx@Dict /msavemtrx known { msavemtrx aload pop } if CM ]
  2242.   def }
  2243. \def\tx@MRestore{%
  2244.   tx@Dict /msavemtrx known { length 0 gt } { false } ifelse
  2245.   { /msavematrx [ msavematrx aload pop setmatrix ] def }
  2246.   if }
  2247. %    \end{macrocode}
  2248. % \end{macro}
  2249. % \begin{macro}{\psmove,\psclosepath,\psgroup}
  2250. %    \begin{macrocode}
  2251. \newtoks\pst@customdefs
  2252. \pst@customdefs{%
  2253.   \def\newpath{\addto@pscode{newpath}}%
  2254.   \def\moveto(#1){\pst@@getcoor{#1}\addto@pscode{\pst@coor moveto}}%
  2255.   \def\closepath{\addto@pscode{closepath}}%
  2256.   \def\gsave{\begingroup\addto@pscode{gsave}}%
  2257.   \def\grestore{\endgroup\addto@pscode{grestore}}%
  2258.   \def\translate(#1){\pst@@getcoor{#1}\addto@pscode{\pst@coor moveto}}%
  2259.   \def\rotate#1{\pst@@getangle{#1}\addto@pscode{\pst@angle rotate}}%
  2260.   \def\scale#1{\pst@getscale{#1}\pst@tempg\addto@pscode{\pst@tempg}}%
  2261.   \def\msave{\addto@pscode{\tx@MSave}}%
  2262.   \def\mrestore{\addto@pscode{\tx@MRestore}}%
  2263.   \def\swapaxes{\addto@pscode{-90 rotate -1 1 scale}}%
  2264.   \def\stroke{\def\pst@par{}\pst@object{stroke}}%
  2265.   \def\fill{\def\pst@par{}\pst@object{fill}}%
  2266.   \def\openshadow{\def\pst@par{}\pst@object{openshadow}}%
  2267.   \def\closedshadow{\def\pst@par{}\pst@object{closedshadow}}%
  2268.   \def\movepath(#1){\pst@@getcoor{#1}\addto@pscode{\pst@coor tx@Shadow}}%
  2269.   \def\lineto{\pst@onecoor{lineto}}%
  2270.   \def\rlineto{\pst@onecoor{rlineto}}%
  2271.   \def\curveto{\pst@threecoor{curveto}}%
  2272.   \def\rcurveto{\pst@threecoor{rcurveto}}%
  2273.   \def\code#1{\addto@pscode{#1}}%
  2274.   \def\coor(#1){\pst@@getcoor{#1}\addto@pscode\pst@coor\@ifnextchar({\coor}{}}%
  2275.   \def\rcoor{\pst@getcoors{}{}}%
  2276.   \def\dim#1{\pssetlength\pst@dimg{#1}\addto@pscode{\pst@number\pst@dimg}}%
  2277.   \def\setcolor#1{%
  2278.     \@ifundefined{color@#1}{}{\addto@pscode{\use@color{#1}}}}%
  2279.   \def\arrows#1{{\psset@arrows{#1}\pst@addarrowdef}}%
  2280.   \let\file\pst@rawfile
  2281. } % END \pst@customdefs
  2282. \def\closedshadow@i{\cuse@par\pst@closedshadow}
  2283. \def\openshadow@i{\cuse@par\pst@openshadow}
  2284. \def\stroke@i{\cuse@par\pst@stroke}%
  2285. \def\fill@i{\cuse@par\pst@fill}%
  2286. \def\pst@onecoor#1(#2){%
  2287.   \pst@@getcoor{#2}%
  2288.   \addto@pscode{\pst@coor #1}}
  2289. \def\pst@threecoor#1(#2)#3(#4)#5(#6){%
  2290.   \begingroup
  2291.     \pst@getcoor{#2}\pst@tempa
  2292.     \pst@getcoor{#4}\pst@tempb
  2293.     \pst@getcoor{#6}\pst@tembc
  2294.     \addto@pscode{\pst@tempa \pst@tempb \pst@tempc #1}%
  2295.   \endgroup}
  2296. %    \end{macrocode}
  2297. % \end{macro}
  2298. % \begin{macro}{\psrawfile,\pst@rawfile}
  2299. %    \begin{macrocode}
  2300. \def\pst@rawfile#1{%
  2301.   \begingroup
  2302.     \def\do##1{\catcode`##1=12\relax}"
  2303.     \dospecials
  2304.     \catcode`\%=14
  2305.     \pst@@rawfile{#1}%
  2306.   \endgroup}
  2307. \def\pst@@rawfile#1{%
  2308.   \immediate\openin1 #1
  2309.   \ifeof1
  2310.     \@pstrickserr{File `#1' not found}\@ehpa
  2311.   \else
  2312.     \immediate\read1 to \pst@tempg
  2313.     \loop
  2314.       \ifeof1 \@pstfalse\else\@psttrue\fi
  2315.     \if@pst
  2316.       \addto@pscode\pst@tempg
  2317.       \immediate\read1 to \pst@tempg
  2318.     \repeat
  2319.   \fi
  2320.   \immediate\closein1\relax}
  2321. %    \end{macrocode}
  2322. % \end{macro}
  2323. % \section{Graphics objects: Basic PostScript macros}
  2324. % \begin{macro}{SD}
  2325. %    \begin{macrocode}
  2326. \pst@def{SD}<%
  2327.   0 360 arc fill>
  2328. \pst@def{SQ}<%
  2329.   /r ED
  2330.   r r moveto
  2331.   r r neg L
  2332.   r neg r neg L
  2333.   r neg r L
  2334.   fill>
  2335. \pst@def{ST}<%
  2336.   /y ED /x ED
  2337.   x y moveto
  2338.   x neg y L
  2339.   0 x L
  2340.   fill>
  2341. \pst@def{SP}<%
  2342.   /r ED
  2343.   gsave
  2344.     0 r moveto
  2345.     4 { 72 rotate 0 r L } repeat
  2346.     fill
  2347.   grestore>
  2348. \@namedef{psds@*}{/Dot { 0 0 DS \tx@SD } def}
  2349. \@namedef{psds@o}{%
  2350.   /r2 DS CLW sub def
  2351.   /Dot { 0 0 DS \tx@SD \pst@usecolor\psfillcolor 0 0 r2 \tx@SD } def}
  2352. \@namedef{psds@square*}{%
  2353.   /r1 DS .886 mul def
  2354.   /Dot { r1 \tx@SQ } def}
  2355. \@namedef{psds@square}{%
  2356.   /r1 DS .886 mul def /r2 r1 CLW sub def
  2357.   /Dot { r1 \tx@SQ \pst@usecolor\psfillcolor r2 \tx@SQ } def}
  2358. \@namedef{psds@triangle*}{%
  2359.   /y1 DS .778 mul neg def /x1 y1 1.732 mul neg def
  2360.   /Dot { x1 y1 \tx@ST } def}
  2361. \@namedef{psds@triangle}{%
  2362.   /y1 DS .778 mul neg def /x1 y1 1.732 mul neg def
  2363.   /y2 y1 CLW add def /x2 y2 1.732 mul neg def
  2364.   /Dot { x1 y1 \tx@ST \pst@usecolor\psfillcolor x2 y2 \tx@ST } def}
  2365. \@namedef{psds@pentagon*}{%
  2366.   /r1 DS 1.149 mul def
  2367.   /Dot { r1 \tx@SP } def}
  2368. \@namedef{psds@pentagon}{%
  2369.   DS .93 mul dup 1.236 mul /r1 ED CLW sub 1.236 mul /r2 ED
  2370.   /Dot { r1 \tx@SP \pst@usecolor\psfillcolor
  2371.     r2 \tx@SP } def}
  2372. \@namedef{psds@+}{%
  2373.   /DS DS 1.253 mul def
  2374.   /Dot { DS 0 moveto DS neg 0 L stroke
  2375.     0 DS moveto 0 DS neg L stroke } def}
  2376. \@namedef{psds@|}{%
  2377.   \psk@tbarsize CLW mul add 2 div /DS ED
  2378.   /Dot { 0 DS moveto 0 DS neg L stroke } def}
  2379. %    \end{macrocode}
  2380. % \end{macro}
  2381. % \begin{macro}{dotstyle}
  2382. %    \begin{macrocode}
  2383. \def\psset@dotstyle#1{%
  2384.   \@ifundefined{psds@#1}%
  2385.     {\@pstrickserr{Dot style `#1' not defined}\@eha}%
  2386.     {\edef\psk@dotstyle{#1}}}
  2387. \psset@dotstyle{*}
  2388. %    \end{macrocode}
  2389. % \end{macro}
  2390. % \begin{macro}{NArray}
  2391. % Syntax:
  2392. % \begin{Ex}
  2393. %   <array of points> NArray <points>
  2394. % \end{Ex}
  2395. % Sets "n" to the number of pairs in the array, and makes sure there is an
  2396. % even number of elements.
  2397. %    \begin{macrocode}
  2398. \pst@def{NArray}<%
  2399.   aload length 2 div dup
  2400.   dup cvi eq not { exch pop } if
  2401.   /n exch cvi def>
  2402. \pst@def{NArray}<%
  2403.   /f ED
  2404.   counttomark 2 div
  2405.   dup cvi /n ED
  2406.   n eq not { exch pop } if
  2407.     { ] aload /Points ED }
  2408.     { n 2 mul 1 add -1 roll pop }
  2409.   ifelse>
  2410. %    \end{macrocode}
  2411. % \end{macro}
  2412. % \begin{macro}{Line}
  2413. % Syntax:
  2414. % \begin{Ex}
  2415. %   <array of points> Line -
  2416. % \end{Ex}
  2417. % "ArrowA" and "ArrowB" should be defined to draw arrows, and "Lineto" should
  2418. % be the procedure used to draw the path; either "lineto" or "Arcto".
  2419. %    \begin{macrocode}
  2420. \pst@def{Line}<%
  2421.   \tx@NArray
  2422.   n 0 eq not
  2423.   { n 1 eq { 0 0 /n 2 def } if
  2424.     ArrowA
  2425.     /n n 2 sub def
  2426.     n { Lineto } repeat
  2427.     CP 4 2 roll ArrowB L
  2428.     pop pop }
  2429.   if>
  2430. %    \end{macrocode}
  2431. % \end{macro}
  2432. % \begin{macro}{Arcto}
  2433. % Syntax:
  2434. % \begin{Ex}
  2435. %   <x2 y2 x1 y1> Arcto <x2 y2>
  2436. % \end{Ex}
  2437. % "r" should be set to the arc radius. Adds to the path with "arcto", with the
  2438. % corner at <x1 y1> and going towards <x2 y2>. Works even when the points are
  2439. % equal. For use with "Line" and "Polygon".
  2440. %    \begin{macrocode}
  2441. \pst@def{Arcto}<%
  2442.   /a [ 6 -2 roll ] cvx def
  2443.   a r /arcto load stopped { 5 } { 4 } ifelse { pop } repeat a>
  2444. %    \end{macrocode}
  2445. % \end{macro}
  2446. % \begin{macro}{Polygon}
  2447. % Syntax:
  2448. % \begin{Ex}
  2449. %   <array of points> Line -
  2450. % \end{Ex}
  2451. % "Lineto" should be the procedure used to draw the path; either "lineto" or
  2452. % "Arcto".
  2453. %    \begin{macrocode}
  2454. \pst@def{CheckClosed}<%
  2455.   dup n 2 mul 1 sub index eq 2 index n 2 mul 1 add index eq and
  2456.   { pop pop /n n 1 sub def }
  2457.   if>
  2458. \pst@def{Polygon}<%
  2459.   \tx@NArray
  2460.   n 2 eq { 0 0 /n 3 def } if
  2461.   n 3 lt
  2462.   { n { pop pop } repeat }
  2463.   { n 3 gt { \tx@CheckClosed } if
  2464.     n 2 mul -2 roll /y0 ED /x0 ED
  2465.     /y1 ED /x1 ED x1 y1
  2466.     /x1 x0 x1 add 2 div def
  2467.     /y1 y0 y1 add 2 div def
  2468.     x1 y1 moveto
  2469.     /n n 2 sub def
  2470.     n { Lineto } repeat
  2471.     x1 y1 x0 y0 6 4 roll
  2472.     Lineto Lineto pop pop closepath }
  2473.   ifelse>
  2474. %    \end{macrocode}
  2475. % \end{macro}
  2476. % \section{Interpolated curves}
  2477. % This documentation is largely junk.
  2478. % There one was an alternate algorithm that had the nice property that when
  2479. % the coordinates were scaled, the interpolated curve would scale in the same
  2480. % way. It was also simpler. However, this one gives nicer looking results in
  2481. % most cases.
  2482. % Two parameters should be defined:
  2483. % \begin{description}
  2484. %   \item[a] Lower values make the curve tighter. (Default: 1)
  2485. % \item[b] Higher values make the curve tighter where the angle ABC is less
  2486. % than 45 degrees, and loosen the curve elsewhere. (Default: .1)
  2487. % \end{description}
  2488. % "ArrowA" and "ArrowB" should be defined as well.
  2489. % Each two points are connected by a single Bezier curve, using curveto. For
  2490. % each point P, let P- and P+ be the control points before and after the
  2491. % point. I.e., If A, B and C are consecutive points, then A and B are
  2492. % connected by the Bezier curve with control points A, A+, B- and B, and B and
  2493. % C are connected with control points B, B+, C- and C.
  2494. % The interpolation is local, meaning that control points B- and B+ depend
  2495. % only on points A, B and C.
  2496. % \begin{macro}{\tx@CCA,\tx@CC}
  2497. % The first three lines before "CCA" set "x1"$=Ax+$, "y1"$=Ay+$,
  2498. % "l0"$=d(A,B)$, "dx0"$=Bx-Ax$, and "dy0"$=By-Ay$. After "CCA", "x"$=Bx$,
  2499. % "y"$=By$, "dx1"$=Cx-Bx$, "dy2"$=Cy-By$, and "l1"$=d(B,C)$.
  2500. %    \begin{macrocode}
  2501. \pst@def{CCA}<%
  2502.   /y ED /x ED 2 copy
  2503.   y sub /dy1 ED x sub /dx1 ED
  2504.   /l1 dx1 dy1 \tx@Pyth def>
  2505. \pst@def{CCA}<%
  2506.   /y ED /x ED 2 copy
  2507.   y sub /dy1 ED x sub /dx1 ED
  2508.   /l1 dx1 dy1 \tx@Pyth def>
  2509. \pst@def{CC}<%
  2510.   /l0 l1 def
  2511.   /x1 x dx sub def /y1 y dy sub def
  2512.   /dx0 dx1 def /dy0 dy1 def
  2513.   \tx@CCA
  2514. %    \end{macrocode}
  2515. % The task is now to calculate $B-$ and $B+$. We first calculate the slope
  2516. % "dx" and "dy" at $B$. This tangent at $B$ should be perpendicular to the
  2517. % bisection of the angle $ABC$. Recalling that "dx0" and "dy0" ``point'' from
  2518. % $A$ to $B$, this tangency thus passes through $B+(dx,dy)$, where $(dx,dy)$
  2519. % is the average of $dx0,dy0$ and $dx1,dy1$, once these have been normalized
  2520. % to have the same length. If we normalize by dividing each by their length,
  2521. % and then multiplying both by both lengths, we get
  2522. % \begin{center}\tt\begin{tabular}{rcl}
  2523. %   dx & $=$ & l1 $\times$ dx0 $+$ l0 $\times$ dx1 \\[3pt]
  2524. %   dy & $=$ & l1 $\times$ dy0 $+$ l0 $\times$ dy1
  2525. % \end{tabular}\end{center}
  2526. %    \begin{macrocode}
  2527.   /dx dx0 l1 c exp mul dx1 l0 c exp mul add def
  2528.   /dy dy0 l1 c exp mul dy1 l0 c exp mul add def
  2529. %    \end{macrocode}
  2530. % "dx" and "dy" give us the direction of the control points $B-$ and $B+$ from
  2531. % $B$. Now we adjust the distance of these control points. The first component
  2532. % is sine of the angle ABC, so that smaller angles give closer control points.
  2533. % This is raised to the "b", so that "b" controls the extent of this
  2534. % dependency (and can even reverse the relation).
  2535. % Then this amount is multiplied times "a", which those adjusts the overall
  2536. % tightness, independently of the angle. Let's call this amount $M$. This
  2537. % amount is then divided by the length of the vector $(dx,dy)$, thereby
  2538. % normalizing this vector to unit length, and then, multiplied times the
  2539. % distance between $A$ and $B$ (for calculating $B-$). Thus, $B-$ is distance
  2540. % $M d(A,B)$ from $B$. $(x2,y2)$ are set to $B-$, thus calculated, and $B+$ is
  2541. % temporily stored in $(dx,dy)$.
  2542. %    \begin{macrocode}
  2543.   /m dx0 dy0 \tx@Atan dx1 dy1 \tx@Atan sub
  2544.      2 div cos abs b exp a mul
  2545.      dx dy \tx@Pyth \tx@Div 2 div def
  2546.   /x2 x l0 dx mul m mul sub def
  2547.   /y2 y l0 dy mul m mul sub def
  2548.   /dx l1 dx mul m mul neg def
  2549.   /dy l1 dy mul m mul neg def>
  2550. %    \end{macrocode}
  2551. % \end{macro}
  2552. % \begin{macro}{\tx@IC,\tx@BOC,\tx@NC,\tx@EOC,\tx@BAC,\tx@NAC,\tx@EAC}
  2553. % These are the compenents of the loops that go through the lists of points
  2554. % that are to be interpolated. These are abbreviations, as follows:
  2555. % \begin{center}
  2556. % \begin{tabular}{ll}
  2557. % "IC" & Initialize Curve\\
  2558. % "BOC" & Begin Open Curve\\
  2559. % "NC" & Next Curve\\
  2560. % "EOC" & End Open Curve\\
  2561. % "BAC" & Begin Alternative Curve\\
  2562. % "NAC" & Next Alternative Curve\\
  2563. % "EAC" & End Alternative Curve
  2564. % \end{tabular}
  2565. % \end{center}
  2566. %    \begin{macrocode}
  2567. \pst@def{IC}<%
  2568.   /c c 1 add def
  2569.   c 0 lt { /c 0 def } { c 3 gt { /c 3 def } if } ifelse
  2570.   /a a 2 mul 3 div 45 cos b exp div def
  2571.   \tx@CCA /dx 0 def /dy 0 def>
  2572. \pst@def{BOC}<%
  2573.   \tx@IC \tx@CC x2 y2 x1 y1 ArrowA
  2574.   CP 4 2 roll x y curveto>
  2575. \pst@def{NC}<\tx@CC x1 y1 x2 y2 x y curveto>
  2576. \pst@def{EOC}<%
  2577.   x dx sub y dy sub 4 2 roll ArrowB 2 copy curveto>
  2578. \pst@def{BAC}<%
  2579.   \tx@IC \tx@CC x y moveto \tx@CC
  2580.   x1 y1 CP ArrowA>
  2581. \pst@def{NAC}<x2 y2 x y curveto \tx@CC x1 y1>
  2582. \pst@def{EAC}<x2 y2 x y ArrowB curveto pop pop>
  2583. %    \end{macrocode}
  2584. % \end{macro}
  2585. % \begin{macro}{OpenCurve}
  2586. % Syntax:
  2587. % \begin{Ex}
  2588. %   <array of points> OpenCurve
  2589. % \end{Ex}
  2590. %    \begin{macrocode}
  2591. \pst@def{OpenCurve}<%
  2592.   \tx@NArray
  2593.   n 3 lt
  2594.   { n { pop pop } repeat }
  2595.   { \tx@BOC
  2596.     /n n 3 sub def
  2597.     n { \tx@NC } repeat
  2598.     \tx@EOC }
  2599.   ifelse>
  2600. %    \end{macrocode}
  2601. % \end{macro}
  2602. % \begin{macro}{AltCurve}
  2603. % Syntax:
  2604. % \begin{Ex}
  2605. %   <array of points> AltCurve
  2606. % \end{Ex}
  2607. %    \begin{macrocode}
  2608. \pst@def{AltCurve}<%
  2609.   { false \tx@NArray
  2610.     n 2 mul 2 roll
  2611.     [ n 2 mul 3 sub 1 roll ]
  2612.     aload /Points ED
  2613.     n 2 mul -2 roll }
  2614.   { false \tx@NArray }
  2615.   ifelse
  2616.   n 4 lt
  2617.   { n { pop pop } repeat }
  2618.   { \tx@BAC
  2619.     /n n 4 sub def
  2620.     n { \tx@NAC } repeat
  2621.     \tx@EAC }
  2622.   ifelse>
  2623. %    \end{macrocode}
  2624. % \end{macro}
  2625. % \begin{macro}{ClosedCurve}
  2626. % Syntax:
  2627. % \begin{Ex}
  2628. %   <array of points> ClosedCurve
  2629. % \end{Ex}
  2630. %    \begin{macrocode}
  2631. \pst@def{ClosedCurve}<%
  2632.   \tx@NArray
  2633.   n 3 lt
  2634.   { n { pop pop } repeat }
  2635.   { n 3 gt { \tx@CheckClosed } if
  2636.     6 copy n 2 mul 6 add 6 roll
  2637.     \tx@IC \tx@CC x y moveto
  2638.     n { \tx@NC } repeat
  2639.    closepath pop pop }
  2640.   ifelse>
  2641. %    \end{macrocode}
  2642. % \end{macro}
  2643. % \begin{macro}{curvature}
  2644. %    \begin{macrocode}
  2645. \def\psset@curvature#1{%
  2646.   \edef\pst@tempg{#1 }%
  2647.   \expandafter\psset@@curvature\pst@tempg * * * \@nil}
  2648. \def\psset@@curvature#1 #2 #3 #4\@nil{%
  2649.   \pst@checknum{#1}\pst@tempg
  2650.   \pst@checknum{#2}\pst@temph
  2651.   \pst@checknum{#3}\pst@tempi
  2652.   \edef\psk@curvature{\pst@tempg \pst@temph \pst@tempi}}
  2653. \psset@curvature{1 .1 0}
  2654. %    \end{macrocode}
  2655. % \end{macro}
  2656. % \begin{macro}{\pscurve}
  2657. %    \begin{macrocode}
  2658. \def\pscurve{\def\pst@par{}\pst@object{pscurve}}
  2659. \def\pscurve@i{%
  2660.   \pst@getarrows{%
  2661.     \begin@OpenObj
  2662.       \pst@getcoors[\pscurve@ii}}
  2663. \def\pscurve@ii{%
  2664.   \addto@pscode{%
  2665.     \pst@cp
  2666.     \psk@curvature\space /c ED /b ED /a ED
  2667.     \ifshowpoints true \else false \fi
  2668.     \tx@OpenCurve}%
  2669.   \end@OpenObj}
  2670. %    \end{macrocode}
  2671. % \end{macro}
  2672. % \begin{macro}{\psecurve}
  2673. %    \begin{macrocode}
  2674. \def\psecurve{\def\pst@par{}\pst@object{psecurve}}
  2675. \def\psecurve@i{%
  2676.   \pst@getarrows{%
  2677.     \begin@OpenObj
  2678.     \pst@getcoors[\psecurve@ii}}
  2679. \def\psecurve@ii{%
  2680.   \addto@pscode{%
  2681.     \psk@curvature\space /c ED /b ED /a ED
  2682.     \ifshowpoints true \else false \fi
  2683.     \tx@AltCurve}%
  2684.   \end@OpenObj}
  2685. %    \end{macrocode}
  2686. % \end{macro}
  2687. % \begin{macro}{\psccurve}
  2688. %    \begin{macrocode}
  2689. \def\psccurve{\def\pst@par{}\pst@object{psccurve}}
  2690. \def\psccurve@i{%
  2691.   \begin@ClosedObj
  2692.     \pst@getcoors[\psccurve@ii}
  2693. \def\psccurve@ii{%
  2694.   \addto@pscode{%
  2695.     \psk@curvature\space /c ED /b ED /a ED
  2696.     \ifshowpoints true \else false \fi
  2697.     \tx@ClosedCurve}%
  2698.   \def\pst@linetype{1}%
  2699.   \end@ClosedObj}
  2700. %    \end{macrocode}
  2701. % \end{macro}
  2702. % \section{Dots}
  2703. % It would be nice to use a font, with hinting.
  2704. % \begin{macro}{dotsize}
  2705. %    \begin{macrocode}
  2706. \def\psset@dotsize#1{%
  2707.   \edef\pst@tempg{#1 }%
  2708.   \expandafter\psset@@dotsize\pst@tempg -1 -1 -1\@nil}
  2709. \def\psset@@dotsize#1 #2 #3\@nil{%
  2710.   \pst@checknum{#2}\pst@tempg
  2711.   \pssetlength\pst@dimg{#1}%
  2712.   \edef\psk@dotsize{%
  2713.     /DS \pst@number\pst@dimg \pst@tempg CLW mul add 2 div def }}
  2714. \psset@dotsize{.5pt 2.5}
  2715. %    \end{macrocode}
  2716. % \end{macro}
  2717. % \begin{macro}{\psset@dotscale}
  2718. %    \begin{macrocode}
  2719. \def\psset@dotscale#1{\pst@getscale{#1}\psk@dotscale}
  2720. \psset@dotscale{1}
  2721. %    \end{macrocode}
  2722. % \end{macro}
  2723. % \begin{macro}{\pst@Getangle}
  2724. %    \begin{macrocode}
  2725. \def\pst@Getangle#1#2{%
  2726.   \pst@getangle{#1}\pst@tempg
  2727.   \def\pst@temph{0. }%
  2728.   \ifx\pst@tempg\pst@temph
  2729.     \def#2{}%
  2730.   \else
  2731.     \edef#2{\pst@tempg\space rotate }%
  2732.   \fi}
  2733. %    \end{macrocode}
  2734. % \end{macro}
  2735. % \begin{macro}{dotangle}
  2736. %    \begin{macrocode}
  2737. \def\psset@dotangle#1{\pst@Getangle{#1}\psk@dotangle}
  2738. \psset@dotangle{0}
  2739. %    \end{macrocode}
  2740. % \end{macro}
  2741. % \begin{macro}{\psdots}
  2742. %    \begin{macrocode}
  2743. \def\psdots{\def\pst@par{}\pst@object{psdots}}
  2744. \def\psdots@i{%
  2745.   \begin@SpecialObj
  2746.     \pst@getcoors[\psdots@ii}
  2747. \def\psdots@ii{%
  2748.    \addto@pscode{false \tx@NArray \psdots@iii}%
  2749.  \end@SpecialObj}
  2750. \def\psdots@iii{%
  2751.   \psk@dotsize
  2752.   \@nameuse{psds@\psk@dotstyle}
  2753.   newpath
  2754.   n { gsave T \psk@dotangle \psk@dotscale Dot grestore } repeat}
  2755. %    \end{macrocode}
  2756. % \end{macro}
  2757. % \begin{macro}{EndDot}
  2758. % Syntax
  2759. % \begin{LVerbatim}
  2760. %   {<fill>} {<displace>} EndDot
  2761. % \end{LVerbatim}
  2762. % "DS" should be defined to be the dot size.
  2763. %    \begin{macrocode}
  2764. \pst@def{EndDot}<%
  2765.   { /z DS def } { /z 0 def } ifelse
  2766.   /b ED
  2767.   0 z DS \tx@SD
  2768.   b { 0 z DS CLW sub \tx@SD } if
  2769.   0 DS z add CLW 4 div sub moveto>
  2770. %    \end{macrocode}
  2771. % \end{macro}
  2772. % \begin{macro}{\psas@oo}
  2773. %    \begin{macrocode}
  2774. \def\psas@oo{{\pst@usecolor\psfillcolor true} true \psk@dotsize \tx@EndDot}
  2775. %    \end{macrocode}
  2776. % \end{macro}
  2777. % \begin{macro}{\psas@o}
  2778. %    \begin{macrocode}
  2779. \def\psas@o{{\pst@usecolor\psfillcolor true} false \psk@dotsize \tx@EndDot}
  2780. %    \end{macrocode}
  2781. % \end{macro}
  2782. % \begin{macro}{\psas@**}
  2783. %    \begin{macrocode}
  2784. \@namedef{psas@**}{{false} true \psk@dotsize \tx@EndDot}
  2785. %    \end{macrocode}
  2786. % \end{macro}
  2787. % \begin{macro}{\psas@*}
  2788. %    \begin{macrocode}
  2789. \@namedef{psas@*}{{false} false \psk@dotsize \tx@EndDot}
  2790. %    \end{macrocode}
  2791. % \end{macro}
  2792. % \section{Lines and polygons\label{Lines}}
  2793. % \begin{macro}{linearc}
  2794. %    \begin{macrocode}
  2795. \newdimen\pslinearc
  2796. \def\psset@linearc#1{\pssetlength\pslinearc{#1}}
  2797. \psset@linearc{0pt}
  2798. %    \end{macrocode}
  2799. % \end{macro}
  2800. % \begin{macro}{\psline}
  2801. %    \begin{macrocode}
  2802. \def\psline{\def\pst@par{}\pst@object{psline}}
  2803. \def\psline@i{%
  2804.   \pst@getarrows{%
  2805.     \begin@OpenObj
  2806.       \pst@getcoors[\psline@ii}}
  2807. \def\psline@ii{%
  2808.     \addto@pscode{\pst@cp \psline@iii \tx@Line}%
  2809.   \end@OpenObj}
  2810. \def\psline@iii{%
  2811.   \ifdim\pslinearc>\z@
  2812.     /r \pst@number\pslinearc def
  2813.     /Lineto { \tx@Arcto } def
  2814.   \else
  2815.     /Lineto /lineto load def
  2816.   \fi
  2817.   \ifshowpoints true \else false \fi}
  2818. %    \end{macrocode}
  2819. % \end{macro}
  2820. % \begin{macro}{\qline}
  2821. %    \begin{macrocode}
  2822. \def\qline(#1)(#2){%
  2823.   \def\pst@par{}%
  2824.   \begin@SpecialObj
  2825.     \def\pst@linetype{0}%
  2826.     \pst@getcoor{#1}\pst@tempa
  2827.     \pst@@getcoor{#2}%
  2828.     \addto@pscode{%
  2829.       \pst@tempa moveto \pst@coor L
  2830.       \@nameuse{psls@\pslinestyle}}%
  2831.   \end@SpecialObj}
  2832. %    \end{macrocode}
  2833. % \end{macro}
  2834. % \begin{macro}{\pspolygon}
  2835. %    \begin{macrocode}
  2836. \def\pspolygon{\def\pst@par{}\pst@object{pspolygon}}
  2837. \def\pspolygon@i{%
  2838.   \begin@ClosedObj
  2839.     \def\pst@cp{}%
  2840.     \pst@getcoors[\pspolygon@ii}
  2841. \def\pspolygon@ii{%
  2842.     \addto@pscode{\psline@iii \tx@Polygon}%
  2843.     \def\pst@linetype{1}%
  2844.   \end@ClosedObj}
  2845. %    \end{macrocode}
  2846. % \end{macro}
  2847. % \begin{macro}{framearc}
  2848. %    \begin{macrocode}
  2849. \def\psset@framearc#1{\pst@checknum{#1}\psk@framearc}
  2850. \psset@framearc{0}
  2851. %    \end{macrocode}
  2852. % \end{macro}
  2853. % \begin{macro}{cornersize}
  2854. %    \begin{macrocode}
  2855. \def\psset@cornersize#1{%
  2856.   \pst@expandafter\psset@@cornersize{#1}\@nil}
  2857. \def\psset@@cornersize#1#2\@nil{%
  2858.   \if #1a\relax
  2859.     \def\psk@cornersize{\pst@number\pslinearc false }%
  2860.   \else
  2861.     \def\psk@cornersize{\psk@framearc true }%
  2862.   \fi}
  2863. \psset@cornersize{relative}
  2864. %    \end{macrocode}
  2865. % \end{macro}
  2866. % \begin{macro}{Frame}
  2867. % Syntax
  2868. % \begin{Ex}
  2869. %   <framearc/linearc bool x1 y1 x2 y2 dimen> "Frame"
  2870. % \end{Ex}
  2871. %    \begin{macrocode}
  2872. \pst@def{Rect}<%
  2873.   x1 y1 y2 add 2 div moveto
  2874.   x1 y2 lineto
  2875.   x2 y2 lineto
  2876.   x2 y1 lineto
  2877.   x1 y1 lineto
  2878.   closepath>
  2879. \pst@def{OvalFrame}<%
  2880.   x1 x2 eq y1 y2 eq or
  2881.   { pop pop x1 y1 moveto x2 y2 L }
  2882.   { y1 y2 sub abs x1 x2 sub abs
  2883.     2 copy gt { exch pop } { pop } ifelse
  2884.     2 div
  2885.     exch   % STACK: cornersize halfwidth boolean
  2886.     { dup 3 1 roll mul exch }
  2887.     if
  2888.     2 copy lt { pop } { exch pop } ifelse
  2889.     /b ED
  2890.     x1 y1 y2 add 2 div moveto
  2891.     x1 y2 x2 y2 b arcto
  2892.     x2 y2 x2 y1 b arcto
  2893.     x2 y1 x1 y1 b arcto
  2894.     x1 y1 x1 y2 b arcto
  2895.     16 { pop } repeat
  2896.     closepath }
  2897.   ifelse>
  2898. \pst@def{Frame}<%
  2899.   CLW mul /a ED
  2900.   3 -1 roll 2 copy gt { exch } if
  2901.   a sub /y2 ED a add /y1 ED
  2902.   2 copy gt { exch } if
  2903.   a sub /x2 ED a add /x1 ED
  2904.   1 index 0 eq { pop pop \tx@Rect } { \tx@OvalFrame } ifelse>
  2905. %    \end{macrocode}
  2906. % \end{macro}
  2907. % \begin{macro}{dimen}
  2908. %    \begin{macrocode}
  2909. \def\psset@dimen#1{%
  2910.   \pst@expandafter\psset@@dimen{#1}\@nil}
  2911. \def\psset@@dimen#1#2\@nil{%
  2912.   \if #1o\relax
  2913.     \def\psk@dimen{.5 }%
  2914.   \else
  2915.     \if #1m\relax
  2916.       \def\psk@dimen{0 }%
  2917.     \else
  2918.       \if #1i\relax
  2919.         \def\psk@dimen{-.5 }%
  2920.       \fi
  2921.     \fi
  2922.   \fi}
  2923. \psset@dimen{outer}
  2924. %    \end{macrocode}
  2925. % \end{macro}
  2926. % \begin{macro}{\psframe}
  2927. %    \begin{macrocode}
  2928. \def\psframe{\def\pst@par{}\pst@object{psframe}}
  2929. \def\psframe@i(#1){%
  2930.   \@ifnextchar({\psframe@ii(#1)}{\psframe@ii(0,0)(#1)}}
  2931. \def\psframe@ii(#1)(#2){%
  2932.   \begin@ClosedObj
  2933.     \pst@getcoor{#1}\pst@tempa
  2934.     \pst@@getcoor{#2}%
  2935.     \addto@pscode{\psk@cornersize \pst@tempa \pst@coor \psk@dimen \tx@Frame}%
  2936.     \def\pst@linetype{2}%
  2937.     \showpointsfalse
  2938.   \end@ClosedObj}
  2939. %    \end{macrocode}
  2940. % \end{macro}
  2941. % \section{Curves}
  2942. % \begin{macro}{\psbezier}
  2943. %    \begin{macrocode}
  2944. \def\psbezier{\def\pst@par{}\pst@object{psbezier}}
  2945. \def\psbezier@i{\pst@getarrows\psbezier@ii}
  2946. \def\psbezier@ii#1(#2)#3(#4)#5(#6){%
  2947.   \@ifnextchar({\psbezier@iii{1}(#2)(#4)(#6)}%
  2948.     {\psbezier@iii{\z@}(0,0)(#2)(#4)(#6)}}
  2949. \def\psbezier@iii#1(#2)(#3)(#4)(#5){%
  2950.   \begin@OpenObj
  2951.   \pst@getcoor{#2}\pst@tempa
  2952.   \pst@getcoor{#3}\pst@tempb
  2953.   \pst@getcoor{#4}\pst@tempc
  2954.   \pst@getcoor{#5}\pst@tempd
  2955.   \pst@optcp{#1}\pst@tempa
  2956.   \ifshowpoints\psbezier@iv\fi
  2957.   \addto@pscode{
  2958.     \pst@tempb \pst@tempa ArrowA
  2959.     \pst@tempc \pst@tempd ArrowB
  2960.     curveto}%
  2961.   \end@OpenObj}
  2962. \def\psbezier@iv{%
  2963.   \addto@pscode{%
  2964.     gsave
  2965.       \pst@tempa \pst@tempb \pst@tempc \pst@tempd
  2966.        newpath moveto L L L
  2967.        CLW 2 div SLW
  2968.        [ \psk@dash\space ] 0 setdash stroke
  2969.     grestore
  2970.     /Points [\pst@tempa\pst@tempb\pst@tempc\pst@tempd] def}}
  2971. %    \end{macrocode}
  2972. % \end{macro}
  2973. % \begin{macro}{\parabola}
  2974. %    \begin{macrocode}
  2975. \pst@def{Parab}<%
  2976.   /y0 exch def
  2977.   /x0 exch def
  2978.   /y1 exch def
  2979.   /x1 exch def
  2980.   /dx x0 x1 sub 3 div def
  2981.   /dy y0 y1 sub 3 div def
  2982.   x0 dx sub y0 dy add x1 y1 ArrowA
  2983.   x0 dx add y0 dy add x0 2 mul x1 sub y1 ArrowB
  2984.   curveto
  2985.   /Points [ x1 y1 x0 y0 x0 2 mul x1 sub y1 ] def>
  2986. \def\parabola{\def\pst@par{}\pst@object{parabola}}
  2987. \def\parabola@i{\pst@getarrows\parabola@ii}
  2988. \def\parabola@ii#1(#2)#3(#4){%
  2989.   \begin@OpenObj
  2990.     \pst@getcoor{#2}\pst@tempa
  2991.     \pst@@getcoor{#4}%
  2992.     \addto@pscode{\pst@tempa \pst@coor \tx@Parab}%
  2993.   \end@OpenObj}
  2994. %    \end{macrocode}
  2995. % \end{macro}
  2996. % \section{Grids\label{Grids}}
  2997. % \begin{macro}{gridwidth}
  2998. %    \begin{macrocode}
  2999. \def\psset@gridwidth#1{\pst@getlength{#1}\psk@gridwidth}
  3000. \psset@gridwidth{.8pt}
  3001. %    \end{macrocode}
  3002. % \end{macro}
  3003. % \begin{macro}{griddots}
  3004. %    \begin{macrocode}
  3005. \def\psset@griddots#1{%
  3006.   \pst@cntg=#1\relax
  3007.   \edef\psk@griddots{\the\pst@cntg}}
  3008. \psset@griddots{0}
  3009. %    \end{macrocode}
  3010. % \end{macro}
  3011. % \begin{macro}{gridcolor}
  3012. %    \begin{macrocode}
  3013. \def\psset@gridcolor#1{\pst@getcolor{#1}\psgridcolor}
  3014. \psset@gridcolor{black}
  3015. %    \end{macrocode}
  3016. % \end{macro}
  3017. % \begin{macro}{subgridwidth}
  3018. %    \begin{macrocode}
  3019. \def\psset@subgridwidth#1{\pst@getlength{#1}\psk@subgridwidth}
  3020. \psset@subgridwidth{.4pt}
  3021. %    \end{macrocode}
  3022. % \end{macro}
  3023. % \begin{macro}{subgridcolor}
  3024. %    \begin{macrocode}
  3025. \def\psset@subgridcolor#1{\pst@getcolor{#1}\pssubgridcolor}
  3026. \psset@subgridcolor{gray}
  3027. %    \end{macrocode}
  3028. % \end{macro}
  3029. % \begin{macro}{subgriddots}
  3030. %    \begin{macrocode}
  3031. \def\psset@subgriddots#1{%
  3032.   \pst@cntg=#1\relax\edef\psk@subgriddots{\the\pst@cntg}}
  3033. \psset@subgriddots{0}
  3034. %    \end{macrocode}
  3035. % \end{macro}
  3036. % \begin{macro}{subgriddiv}
  3037. %    \begin{macrocode}
  3038. \def\psset@subgriddiv#1{%
  3039.   \pst@cntg=#1\relax\edef\psk@subgriddiv{\the\pst@cntg}}
  3040. \psset@subgriddiv{5}
  3041. %    \end{macrocode}
  3042. % \end{macro}
  3043. % \begin{macro}{gridlabels}
  3044. %    \begin{macrocode}
  3045. \def\psset@gridlabels#1{\pst@getlength{#1}\psk@gridlabels}
  3046. \psset@gridlabels{10pt}
  3047. %    \end{macrocode}
  3048. % \end{macro}
  3049. % \begin{macro}{gridlabelcolor}
  3050. %    \begin{macrocode}
  3051. \def\psset@gridlabelcolor#1{\pst@getcolor{#1}\psgridlabelcolor}
  3052. \psset@gridlabelcolor{black}
  3053. %    \end{macrocode}
  3054. % \end{macro}
  3055. % \begin{macro}{Grid}
  3056. % Syntax:
  3057. % \begin{Ex}
  3058. %   <x1 y1 x2 y2 x-origin y-origin x-divsize y-divsize>\\
  3059. %   <numsubdiv griddots labelcolor labelsize> "Grid"
  3060. % \end{Ex}
  3061. % Coordinates should all be integers. Font needs to be defined before invoking
  3062. % this procedure. This could probably be simplified.
  3063. %    \begin{macrocode}
  3064. \pst@def{Grid}<%
  3065.   /a 4 string def            % Empty string
  3066.   /b ED                      % Label size
  3067.   /d ED                      % Label color procedure.
  3068.   /n ED                      % Number of grid dots
  3069.   cvi dup 1 lt { pop 1 } if /c ED   % Number subdivisions
  3070.   c div dup 0 eq { pop 1 } if /cy ED
  3071.   c div dup 0 eq { pop 1 } if /cx ED  % division spacing
  3072.   cy div cvi /y ED     % origin y
  3073.   cx div cvi /x ED     % origin x
  3074.   cy div cvi /y2 ED    % y2
  3075.   cx div cvi /x2 ED    % x2
  3076.   cy div cvi /y1 ED    % y1
  3077.   cx div cvi /x1 ED    % x1
  3078.   /h y2 y1 sub 0 gt { 1 } { -1 } ifelse def  % Sign of y2-y1
  3079.   /w x2 x1 sub 0 gt { 1 } { -1 } ifelse def  % Sign of x2-x1
  3080.   b 0 gt
  3081.   { /z1 b 4 div CLW 2 div add def
  3082.     /Helvetica findfont b scalefont setfont
  3083.     /b b .95 mul CLW 2 div add def }
  3084.   gsave
  3085.   n 0 gt
  3086.   { 1 setlinecap [ 0 cy n div ] 0 setdash }
  3087.   { 2 setlinecap }
  3088.   ifelse
  3089.   /c x1 def /i 500 w mul x1 add def        % Index
  3090.   /e y cy mul def /f y1 cy mul def /g y2 cy mul def
  3091.   x1 cx mul 0 T
  3092.   { newpath
  3093.     0 e moveto
  3094.     b 0 gt
  3095.     { gsave d c a cvs dup
  3096.       stringwidth pop /z2 ED
  3097.       w 0 gt {z1} {z1 z2 add neg} ifelse
  3098.       h 0 gt {b neg} {z1} ifelse
  3099.       rmoveto show grestore } if
  3100.     0 f moveto 0 g L stroke
  3101.     cx w mul 0 T
  3102.     c x2 eq c i eq or {exit} if
  3103.     /c c w add def
  3104.   } loop
  3105.   grestore
  3106.   gsave
  3107.   n 0 gt
  3108.   { 1 setlinecap [ 0 cx n div ] 0 setdash }
  3109.   { 2 setlinecap }
  3110.   ifelse
  3111.   /c y1 def /i 500 h mul y1 add def
  3112.   /e x cx mul def /f x1 cx mul def /g x2 cx mul def
  3113.   0 y1 cy mul T
  3114.   { newpath
  3115.     e 0 moveto
  3116.     b 0 gt { gsave d
  3117.       c a cvs dup
  3118.       stringwidth pop /z2 ED
  3119.       w 0 gt {z1 z2 add neg} {z1} ifelse
  3120.       h 0 gt {z1} {b neg} ifelse
  3121.       rmoveto show grestore } if
  3122.     f 0 moveto g 0 L stroke
  3123.     0 cy h mul T
  3124.     c y2 eq c i eq or {exit} if
  3125.     /c c h add def
  3126.   } loop
  3127.   grestore>
  3128. %    \end{macrocode}
  3129. % \end{macro}
  3130. % \begin{macro}{\psgrid}
  3131. %    \begin{macrocode}
  3132. \def\psgrid{\def\pst@par{}\pst@object{psgrid}}
  3133. \def\psgrid@i{\@ifnextchar(%
  3134.   {\psgrid@ii}{\expandafter\psgrid@iv\pic@coor}}
  3135. \def\psgrid@ii(#1){\@ifnextchar(%
  3136.   {\psgrid@iii(#1)}{\psgrid@iv(0,0)(0,0)(#1)}}
  3137. \def\psgrid@iii(#1)(#2){\@ifnextchar(%
  3138.   {\psgrid@iv(#1)(#2)}{\psgrid@iv(#1)(#1)(#2)}}
  3139. \def\psgrid@iv(#1)(#2)(#3){%
  3140.   \begin@SpecialObj
  3141.   \pst@getcoor{#1}\pst@tempa
  3142.   \pst@getcoor{#2}\pst@tempb
  3143.   \pst@@getcoor{#3}%
  3144.   \ifnum\psk@subgriddiv>1
  3145.     \addto@pscode{gsave
  3146.     \psk@subgridwidth SLW \pst@usecolor\pssubgridcolor
  3147.     \pst@tempb \pst@coor \pst@tempa
  3148.     \pst@number\psxunit \pst@number\psyunit
  3149.     \psk@subgriddiv\space \psk@subgriddots\space
  3150.     {} 0 \tx@Grid grestore}%
  3151.   \fi
  3152.   \addto@pscode{gsave
  3153.     \psk@gridwidth SLW \pst@usecolor\psgridcolor
  3154.     \pst@tempb \pst@coor \pst@tempa
  3155.     \pst@number\psxunit \pst@number\psyunit
  3156.     1 \psk@griddots\space { \pst@usecolor\psgridlabelcolor }
  3157.     \psk@gridlabels \tx@Grid grestore}%
  3158.   \end@SpecialObj}
  3159. %    \end{macrocode}
  3160. % \end{macro}
  3161. % \section{LR-box commands}
  3162. % \begin{macro}{\ifpsmathbox,\everypsbox}
  3163. %    \begin{macrocode}
  3164. \newif\ifpsmathbox
  3165. \psmathboxtrue
  3166. \def\pst@mathflag{\z@}
  3167. \newtoks\everypsbox
  3168. %    \end{macrocode}
  3169. % \end{macro}
  3170. % \begin{macro}{\pst@makenotverbbox}
  3171. %    \begin{macrocode}
  3172. \long\def\pst@makenotverbbox#1#2{%
  3173.   \edef\pst@mathflag{%
  3174.     \ifpsmathbox\ifmmode\ifinner 1\else 2\fi\else \z@\fi\else \z@\fi}%
  3175.   \setbox\pst@hbox=\hbox{%
  3176.     \ifcase\pst@mathflag\or$\m@th\textstyle\or$\m@th\displaystyle\fi
  3177.     {\the\everypsbox#2}%
  3178.     \ifnum\pst@mathflag>\z@$\fi}%
  3179.   #1}
  3180. %    \end{macrocode}
  3181. % \end{macro}
  3182. % \begin{macro}{\pst@makeverbbox}
  3183. % There is no way to do this such that with
  3184. % \begin{LVerbatim}
  3185. %   \psframebox{\aftergroup\foo}
  3186. % \end{LVerbatim}
  3187. % "\foo" does not end up outside the box. That is why this is not the default
  3188. % mode.
  3189. %    \begin{macrocode}
  3190. \def\pst@makeverbbox#1{%
  3191.   \def\pst@afterbox{#1}%
  3192.   \edef\pst@mathflag{%
  3193.     \ifpsmathbox\ifmmode\ifinner 1\else 2\fi\else \z@\fi\else \z@\fi}%
  3194.   \afterassignment\pst@beginbox
  3195.   \setbox\pst@hbox\hbox}
  3196. \def\pst@beginbox{%
  3197.   \ifcase\pst@mathflag\or$\m@th\or$\m@th\displaystyle\fi
  3198.   \bgroup\aftergroup\pst@endbox
  3199.   \the\everypsbox}
  3200. \def\pst@endbox{%
  3201.   \ifnum\pst@mathflag>\z@$\fi
  3202.   \egroup
  3203.   \pst@afterbox}
  3204. %    \end{macrocode}
  3205. % \end{macro}
  3206. % \begin{macro}{\psverbboxtrue,\psverbboxfalse}
  3207. %    \begin{macrocode}
  3208. \def\pst@makebox{\pst@@makebox}
  3209. \def\psverbboxtrue{\def\pst@@makebox{\pst@makeverbbox}}
  3210. \def\psverbboxfalse{\def\pst@@makebox{\pst@makenotverbbox}}
  3211. \psverbboxfalse
  3212. %    \end{macrocode}
  3213. % \end{macro}
  3214. % \begin{macro}{\pst@longbox,\pst@makelongbox}
  3215. % There is no way to do this such that with
  3216. % \begin{LVerbatim}
  3217. %   \psframebox{\aftergroup\foo}
  3218. % \end{LVerbatim}
  3219. % "\foo" does not end up outside the box. That is why this is not the default
  3220. % mode.
  3221. %    \begin{macrocode}
  3222. \def\pst@longbox{%
  3223.   \def\pst@makebox{%
  3224.     \gdef\pst@makebox{\pst@@makebox}%
  3225.     \pst@makelongbox}}
  3226. \def\pst@makelongbox#1{%
  3227.   \def\pst@afterbox{#1}%
  3228.   \edef\pst@mathflag{%
  3229.     \ifpsmathbox\ifmmode\ifinner 1\else 2\fi\else \z@\fi\else \z@\fi}%
  3230.   \setbox\pst@hbox\hbox\bgroup
  3231.     \aftergroup\pst@afterbox
  3232.     \ifcase\pst@mathflag\or$\m@th\or$\m@th\displaystyle\fi
  3233.     \begingroup
  3234.       \the\everypsbox}
  3235. \def\pst@endlongbox{%
  3236.      \endgroup
  3237.      \ifnum\pst@mathflag>\z@$\fi
  3238.    \egroup}
  3239. %    \end{macrocode}
  3240. % \end{macro}
  3241. % \begin{macro}{\pslongbox}
  3242. %    \begin{macrocode}
  3243. \def\pslongbox#1#2{%
  3244.   \@namedef{#1}{\pst@longbox#2}%
  3245.   \@namedef{end#1}{\pst@endlongbox}}
  3246. %    \end{macrocode}
  3247. % \end{macro}
  3248. % \section{Frame boxes\label{Frameboxes}}
  3249. % \begin{macro}{framesep}
  3250. %    \begin{macrocode}
  3251. \newdimen\psframesep
  3252. \def\psset@framesep#1{\pssetlength\psframesep{#1}}
  3253. \psset@framesep{3pt}
  3254. %    \end{macrocode}
  3255. % \end{macro}
  3256. % \begin{macro}{boxsep}
  3257. %    \begin{macrocode}
  3258. \newif\ifpsboxsep
  3259. \def\psset@boxsep#1{\@nameuse{psboxsep#1}}
  3260. \psset@boxsep{true}
  3261. %    \end{macrocode}
  3262. % \end{macro}
  3263. % \begin{macro}{\pst@useboxpar}
  3264. %    \begin{macrocode}
  3265. \def\pst@useboxpar{%
  3266.   \use@par
  3267.   \if@star
  3268.     \let\pslinecolor\psfillcolor
  3269.     \solid@star
  3270.     \let\solid@star\relax
  3271.   \fi
  3272.   \ifpsdoubleline \pst@setdoublesep \fi}
  3273. %    \end{macrocode}
  3274. % \end{macro}
  3275. % \begin{macro}{\psframebox}
  3276. % "\psframebox" puts its argument in an "\hbox" and draws a frame around it
  3277. % with thickness "\pst@linewidth", and with distance "\pst@framesep" between
  3278. % each side of the frame (between the line making up each side) and each side
  3279. % of the box. The result is a box with no depth and with width and height
  3280. % equal to the width and height of the original box, plus
  3281. % 2("\pslinewidth"+"\psframesep").
  3282. % "\pst@dima" is set to the distance between each side of the original box and
  3283. % the outer side of the frame (i.e., the side of the resulting box).
  3284. % "\pst@dimb" is set to the depth of the resulting box, "\pst@dimc" is set to
  3285. % the height plus depth of this box, and "\pst@dimd" is set to the width.
  3286. % "\psframe" does the drawing of the frame.
  3287. %    \begin{macrocode}
  3288. \def\psframebox{\def\pst@par{}\pst@object{psframebox}}
  3289. \def\psframebox@i{\pst@makebox\psframebox@ii}
  3290. \def\psframebox@ii{%
  3291.   \begingroup
  3292.     \pst@useboxpar
  3293.     \pst@dima=\pslinewidth
  3294.     \advance\pst@dima by \psframesep
  3295.     \pst@dimc=\wd\pst@hbox\advance\pst@dimc by \pst@dima
  3296.     \pst@dimb=\dp\pst@hbox\advance\pst@dimb by \pst@dima
  3297.     \pst@dimd=\ht\pst@hbox\advance\pst@dimd by \pst@dima
  3298.     \setbox\pst@hbox=\hbox{%
  3299.       \ifpsboxsep\kern\pst@dima\fi
  3300.       \begin@ClosedObj
  3301.         \addto@pscode{%
  3302.           \psk@cornersize
  3303.           \pst@number\pst@dima neg
  3304.           \pst@number\pst@dimb neg
  3305.           \pst@number\pst@dimc
  3306.           \pst@number\pst@dimd
  3307.           .5
  3308.           \tx@Frame}%
  3309.         \def\pst@linetype{2}%
  3310.         \showpointsfalse
  3311.       \end@ClosedObj
  3312.       \box\pst@hbox
  3313.       \ifpsboxsep\kern\pst@dima\fi}%
  3314.     \ifpsboxsep\dp\pst@hbox=\pst@dimb\ht\pst@hbox=\pst@dimd\fi
  3315.     \leavevmode\box\pst@hbox
  3316.   \endgroup}
  3317. %    \end{macrocode}
  3318. % \end{macro}
  3319. % \begin{macro}{\psdblframebox}
  3320. %    \begin{macrocode}
  3321. \def\psdblframebox{\def\pst@par{}\pst@object{psdblframebox}}
  3322. \def\psdblframebox@i{\addto@par{doubleline=true}\psframebox@i}
  3323. %    \end{macrocode}
  3324. % \end{macro}
  3325. % \begin{macro}{\psclip,\endclip}
  3326. % Clipping involves drawing graphics objects, not grouped by "gsave" and
  3327. % "grestore", which may affect the graphics environment. Furthermore, to reset
  3328. % the clipping path, we must either use "grestore" or "initclip", neither of
  3329. % which is robust.
  3330. %    \begin{macrocode}
  3331. \def\psclip#1{%
  3332.   \leavevmode
  3333.   \begingroup
  3334.     \begin@psclip
  3335.     \begingroup
  3336.       \def\use@pscode{%
  3337.         \pstVerb{%
  3338.           \pst@dict
  3339.             /mtrxc CM def
  3340.             CP CP T
  3341.             \tx@STV
  3342.             \psk@origin
  3343.             \psk@swapaxes
  3344.             newpath
  3345.             \pst@code
  3346.             clip
  3347.             newpath
  3348.             mtrxc setmatrix
  3349.             moveto
  3350.             0 setgray
  3351.           end}%
  3352.         \gdef\pst@code{}}%
  3353.         \def\@multips(##1)(##2)##3##4{\pst@misplaced\multips}%
  3354.         \def\nc@object##1##2##3##4{\pst@misplaced{node connection}}%
  3355.         \hbox to\z@{#1}%
  3356.     \endgroup
  3357.   \def\endpsclip{%
  3358.     \end@psclip
  3359.     \endgroup}%
  3360.   \ignorespaces}
  3361. \def\endpsclip{\pst@misplaced\endpsclip}
  3362. \let\begin@psclip\relax
  3363. \def\end@psclip{\pstVerb{currentpoint initclip moveto}}
  3364. \def\AltClipMode{%
  3365.   \def\end@psclip{\pstVerb{\pst@grestore}}%
  3366.   \def\begin@psclip{\pstVerb{gsave}}}
  3367. %    \end{macrocode}
  3368. % \end{macro}
  3369. % \begin{macro}{\psclipbox}
  3370. %    \begin{macrocode}
  3371. \def\clipbox{\@ifnextchar[{\psclipbox@}{psclipbox@[\z@]}}
  3372. \def\clipbox@[#1]{\pst@makebox\psclipbox@@{#1}}
  3373. \def\clipbox@@#1{%
  3374.   \pssetlength\pst@dimg{#1}%
  3375.   \leavevmode\hbox{%
  3376.     \begin@psclip
  3377.     \pst@Verb{%
  3378.       CM \tx@STV CP T newpath
  3379.       /a \pst@number\pst@dimg def
  3380.       /w \pst@number{\wd\pst@hbox}a add def
  3381.       /d \pst@number{\dp\pst@hbox}a add neg def
  3382.       /h \pst@number{\ht\pst@hbox}a add def
  3383.       a neg d moveto
  3384.       a neg h L
  3385.       w h L
  3386.       w d L
  3387.       closepath
  3388.       clip
  3389.       newpath
  3390.       0 0 moveto
  3391.       setmatrix}%
  3392.     \unhbox\pst@hbox
  3393.     \end@psclip}}
  3394. %    \end{macrocode}
  3395. % \end{macro}
  3396. % \begin{macro}{\psshadowbox}
  3397. %    \begin{macrocode}
  3398. \def\psshadowbox{%
  3399.   \def\pst@par{}\pst@object{psshadowbox}}
  3400. \def\psshadowbox@i{\pst@makebox\psshadowbox@ii}
  3401. \def\psshadowbox@ii{%
  3402.   \begingroup
  3403.     \pst@useboxpar
  3404.     \psshadowtrue
  3405.     \psboxseptrue
  3406.     \def\psk@shadowangle{-45 }%
  3407.     \setbox\pst@hbox=\hbox{\psframebox@ii}%
  3408.     \pst@dimh=\psk@shadowsize\p@
  3409.     \pst@dimh=.7071\pst@dimh
  3410.     \pst@dimg=\dp\pst@hbox
  3411.     \advance\pst@dimg\pst@dimh
  3412.     \dp\pst@hbox=\pst@dimg
  3413.     \pst@dimg=\wd\pst@hbox
  3414.     \advance\pst@dimg\pst@dimh
  3415.     \wd\pst@hbox=\pst@dimg
  3416.     \leavevmode
  3417.     \box\pst@hbox
  3418.   \endgroup}
  3419. % \begin{macro}{\pscirclebox}
  3420. % "\pscirclebox@ii"'s argument is a hook that is used by node commands.
  3421. %    \begin{macrocode}
  3422. \def\pscirclebox{\def\pst@par{}\pst@object{pscirclebox}}
  3423. \def\pscirclebox@i{\pst@makebox{\pscirclebox@ii{}}}
  3424. \def\pscirclebox@ii#1{%
  3425.   \begingroup
  3426.     \pst@useboxpar
  3427.     \setbox\pst@hbox=\hbox{#1\pscirclebox@iii\box\pst@hbox}%
  3428.     \ifpsboxsep
  3429.       \pst@dima=.5\wd\pst@hbox
  3430.       \pst@pyth\pst@dima\pst@dimb\pst@dimc
  3431.       \advance\pst@dimc\pslinewidth
  3432.       \advance\pst@dimc\psframesep
  3433.       \setbox\pst@hbox=\hbox to2\pst@dimc{%
  3434.         \hss
  3435.         \vbox{\vskip\pst@dimc\vskip-\pst@dimb\box\pst@hbox}%
  3436.         \hss}%
  3437.       \advance\pst@dimc-\pst@dimb
  3438.       \dp\pst@hbox=\pst@dimc
  3439.     \fi
  3440.     \leavevmode\box\pst@hbox
  3441.   \endgroup}
  3442. \def\pscirclebox@iii{%
  3443.   \if@star
  3444.     \pslinewidth\z@
  3445.     \pstverb{\pst@dict \tx@STP \pst@usecolor\psfillcolor
  3446.       newpath \pscirclebox@iv \tx@SD end}%
  3447.   \else
  3448.     \begin@ClosedObj
  3449.     \def\pst@linetype{4}\showpointsfalse
  3450.     \addto@pscode{%
  3451.       \pscirclebox@iv CLW 2 div add 0 360 arc closepath}%
  3452.     \end@ClosedObj
  3453.   \fi}
  3454. \def\pscirclebox@iv{%
  3455.   \pst@number{\wd\pst@hbox}2 div
  3456.   \pst@number{\ht\pst@hbox}\pst@number{\dp\pst@hbox}add 2 div
  3457.   2 copy \pst@number{\dp\pst@hbox}sub 4 2 roll
  3458.   \tx@Pyth \pst@number\psframesep add }
  3459. %    \end{macrocode}
  3460. % \end{macro}
  3461. % \begin{macro}{\psovalbox}
  3462. % The argument of "\psovalbox@ii" is a hook used by node commands.
  3463. %    \begin{macrocode}
  3464. \def\psovalbox{\def\pst@par{}\pst@object{psovalbox}}
  3465. \def\psovalbox@i{\pst@makebox{\psovalbox@ii{}}}
  3466. \def\psovalbox@ii#1{%
  3467.   \begingroup
  3468.     \pst@useboxpar
  3469.     \pst@dimd=.707\pslinewidth\advance\pst@dimd by 1.414\psframesep
  3470.     \pst@dimg=\ht\pst@hbox\advance\pst@dimg\dp\pst@hbox
  3471.     \pst@dimb=.707\pst@dimg\advance\pst@dimb\pst@dimd
  3472.     \pst@dima=.707\wd\pst@hbox\advance\pst@dima\pst@dimd
  3473.     \setbox\pst@hbox=\hbox{#1\psovalbox@iii\box\pst@hbox}%
  3474.     \ifpsboxsep
  3475.       \setbox\pst@hbox\hbox to 2\pst@dima{\hss\unhbox\pst@hbox\hss}%
  3476.       \advance\pst@dimb-.5\pst@dimg
  3477.       \pst@dimg\ht\pst@hbox
  3478.       \advance\pst@dimg\pst@dimb
  3479.       \ht\pst@hbox=\pst@dimb
  3480.       \pst@dimg=\dp\pst@hbox
  3481.       \advance\pst@dimg\pst@dimb
  3482.       \dp\pst@hbox=\pst@dimb
  3483.     \fi
  3484.     \leavevmode\box\pst@hbox
  3485.   \endgroup}
  3486. \def\psovalbox@iii{%
  3487.   \begin@ClosedObj
  3488.   \addto@pscode{%
  3489.      0 360
  3490.      \pst@number\pst@dima \pst@number\pst@dimb
  3491.      \pst@number{\wd\pst@hbox}2 div
  3492.      \pst@number\pst@dimg 2 div \pst@number{\dp\pst@hbox}sub
  3493.      \tx@Ellipse
  3494.      closepath}%
  3495.   \def\pst@linetype{2}%
  3496.   \end@ClosedObj}
  3497. %    \end{macrocode}
  3498. % \end{macro}
  3499. % \section{Circles, discs and ellipses\label{Circles}}
  3500. % \begin{macro}{\psset@arcsep,\psk@arcsepA,\psk@arcsepB}
  3501. %    \begin{macrocode}
  3502. \def\psset@arcsepA#1{\pst@getlength{#1}\psk@arcsepA}
  3503. \def\psset@arcsepB#1{\pst@getlength{#1}\psk@arcsepB}
  3504. \def\psset@arcsep#1{%
  3505.   \psset@arcsepA{#1}\let\psk@arcsepB\psk@arcsepA}
  3506. \psset@arcsep{0}
  3507. %    \end{macrocode}
  3508. % \end{macro}
  3509. % \begin{macro}{\tx@Arc}
  3510. % Syntax:
  3511. % \begin{LVerbatim}
  3512. %   <angle> {<arrow>} {<add/sub>} ArcArrow <angle>
  3513. % \end{LVerbatim}
  3514. % "r"=radius and "c"=57.2957/"r" should also be defined.
  3515. %    \begin{macrocode}
  3516. \pst@def{ArcArrow}<%
  3517.   /d ED     % add/sub
  3518.   /b ED     % arrow procedure
  3519.   /a ED     % angle
  3520.   gsave
  3521.     newpath
  3522.     0 -1000 moveto
  3523.     clip              % Set clippath far from arrow.
  3524.     newpath
  3525.     0 1 0 0 b         % Draw arrow to determine length.
  3526.   grestore
  3527.   c mul
  3528.   /e ED               % /e equals angle to adjust for arrow length.
  3529.   pop pop pop
  3530.   r a e d \tx@PtoC    % `a e d' is end angle for arrow.
  3531.   y add exch x add exch
  3532.   r a \tx@PtoC        % Now arrow end coor and begin coor are on stack.
  3533.   y add exch x add exch
  3534.   b pop pop pop pop   % Draw arrow, and discard coordinates.
  3535.   a e d                   % End angle of arrow.
  3536.   CLW 8 div c mul neg d>  % Adjust angle to give a little overlap.
  3537. %    \end{macrocode}
  3538. % \end{macro}
  3539. % \begin{macro}{\psarc}
  3540. %    \begin{macrocode}
  3541. \def\psarc{\def\pst@par{}\pst@object{psarc}}
  3542. \def\psarc@i{%
  3543.   \@ifnextchar({\psarc@iii}{\psarc@ii}}
  3544. \def\psarc@ii#1{\addto@par{arrows=#1}%
  3545.   \@ifnextchar({\psarc@iii}{\psarc@iii(0,0)}}
  3546. \def\psarc@iii(#1)#2#3#4{%
  3547.   \begin@OpenObj
  3548.     \pst@getangle{#3}\pst@tempa
  3549.     \pst@getangle{#4}\pst@tempb
  3550.     \pst@@getcoor{#1}%
  3551.     \pssetlength\pst@dima{#2}%
  3552.     \addto@pscode{\psarc@iv \psarc@v}%
  3553.     \gdef\psarc@type{0}%
  3554.     \showpointsfalse
  3555.   \end@OpenObj}
  3556. \def\psarc@iv{%
  3557.   \pst@coor /y ED /x ED
  3558.   /r \pst@number\pst@dima def
  3559.   /c 57.2957 r \tx@Div def
  3560.   /angleA
  3561.     \pst@tempa
  3562.     \psk@arcsepA c mul 2 div
  3563.     \ifcase \psarc@type add \or sub \fi
  3564.   def
  3565.   /angleB
  3566.     \pst@tempb
  3567.     \psk@arcsepB c mul 2 div
  3568.     \ifcase \psarc@type sub \or add \fi
  3569.   def
  3570.   \ifshowpoints\psarc@showpoints\fi
  3571.   \ifx\psk@arrowA\@empty
  3572.     \ifnum\psk@liftpen=2
  3573.       r angleA \tx@PtoC
  3574.       y add exch x add exch
  3575.       moveto
  3576.     \fi
  3577.   \fi}
  3578. \def\psarc@v{%
  3579.   x y r
  3580.   angleA
  3581.   \ifx\psk@arrowA\@empty\else
  3582.     { ArrowA CP }
  3583.     { \ifcase\psarc@type add \or sub \fi }
  3584.     \tx@ArcArrow
  3585.   \fi
  3586.   angleB
  3587.   \ifx\psk@arrowB\@empty\else
  3588.     { ArrowB }
  3589.     { \ifcase\psarc@type sub \or add \fi }
  3590.     \tx@ArcArrow
  3591.   \fi
  3592.   \ifcase\psarc@type arc \or arcn \fi}
  3593. \def\psarc@type{0}
  3594. \def\psarc@showpoints{%
  3595.   gsave
  3596.     newpath
  3597.     x y moveto
  3598.     x y r \pst@tempa \pst@tempb
  3599.     \ifcase\psarc@type arc \or arcn \fi
  3600.     closepath
  3601.     CLW 2 div SLW
  3602.     [ \psk@dash\space ] 0 setdash stroke
  3603.   grestore }
  3604. %    \end{macrocode}
  3605. % \end{macro}
  3606. % \begin{macro}{\psarcn}
  3607. %    \begin{macrocode}
  3608. \def\psarcn{\def\pst@par{}\pst@object{psarcn}}
  3609. \def\psarcn@i{\def\psarc@type{1}\psarc@i}
  3610. %    \end{macrocode}
  3611. % \end{macro}
  3612. % \begin{macro}{\pscircle}
  3613. %    \begin{macrocode}
  3614. \def\pscircle{\def\pst@par{}\pst@object{pscircle}}
  3615. \def\pscircle@i{\@ifnextchar({\pscircle@do}{\pscircle@do(0,0)}}
  3616. \def\pscircle@do(#1)#2{%
  3617.   \if@star
  3618.     {\use@par\qdisk(#1){#2}}%
  3619.   \else
  3620.     \begin@ClosedObj
  3621.       \pst@@getcoor{#1}%
  3622.       \pssetlength\pst@dimc{#2}%
  3623.       \def\pst@linetype{4}%
  3624.       \addto@pscode{%
  3625.         \pst@coor
  3626.         \pst@number\pst@dimc
  3627.         \psk@dimen CLW mul sub
  3628.         0 360 arc
  3629.         closepath}%
  3630.       \showpointsfalse
  3631.     \end@ClosedObj
  3632.   \fi
  3633.   \ignorespaces}
  3634. %    \end{macrocode}
  3635. % \end{macro}
  3636. % \begin{macro}{\qdisk}
  3637. %    \begin{macrocode}
  3638. \def\qdisk(#1)#2{%
  3639.   \def\pst@par{}%
  3640.   \begin@SpecialObj
  3641.     \pst@@getcoor{#1}%
  3642.     \pssetlength\pst@dimg{#2}%
  3643.     \addto@pscode{\pst@coor \pst@number\pst@dimg \tx@SD}%
  3644.   \end@SpecialObj}
  3645. %    \end{macrocode}
  3646. % \end{macro}
  3647. % \begin{macro}{\pswedge}
  3648. %    \begin{macrocode}
  3649. \def\pswedge{\def\pst@par{}\pst@object{pswedge}}
  3650. \def\pswedge@i{\@ifnextchar({\pswedge@ii}{\pswedge@ii(0,0)}}
  3651. \def\pswedge@ii(#1)#2#3#4{%
  3652.   \begin@ClosedObj
  3653.   \pssetlength\pst@dimc{#2}
  3654.   \pst@getangle{#3}\pst@tempa
  3655.   \pst@getangle{#4}\pst@tempb
  3656.   \pst@@getcoor{#1}%
  3657.   \def\pst@linetype{1}%
  3658.   \addto@pscode{%
  3659.     \pst@coor
  3660.     2 copy
  3661.     moveto
  3662.     \pst@number\pst@dimc \psk@dimen CLW mul sub % Adjusted radius
  3663.     \pst@tempa \pst@tempb
  3664.     arc
  3665.     closepath}%
  3666.     \showpointsfalse
  3667.   \end@ClosedObj}
  3668. %    \end{macrocode}
  3669. % \end{macro}
  3670. % \begin{macro}{Ellipse}
  3671. % Syntax:
  3672. % \begin{Ex}
  3673. %   <angle1 angle2 x-radius y-radius x-origin y-origin> "Ellipse"
  3674. % \end{Ex}
  3675. %    \begin{macrocode}
  3676. \pst@def{Ellipse}<%
  3677.   /mtrx CM def
  3678.   scale
  3679.   0 0 1 5 3 roll arc
  3680.   mtrx setmatrix>
  3681. %    \end{macrocode}
  3682. % \end{macro}
  3683. % \begin{macro}{\psellipse}
  3684. %    \begin{macrocode}
  3685. \def\psellipse{\def\pst@par{}\pst@object{psellipse}}
  3686. \def\psellipse@i(#1){\@ifnextchar(%
  3687.   {\psellipse@ii(#1)}{\psellipse@ii(0,0)(#1)}}
  3688. \def\psellipse@ii(#1)(#2){%
  3689.   \begin@ClosedObj
  3690.     \pst@getcoor{#1}\pst@tempa
  3691.     \pst@@getcoor{#2}%
  3692.     \addto@pscode{%
  3693.       0 360
  3694.       \pst@coor
  3695.       \ifdim\psk@dimen\p@=\z@\else
  3696.         \psk@dimen CLW mul dup 3 1 roll
  3697.         sub 3 1 roll sub exch
  3698.       \fi
  3699.       \pst@tempa
  3700.       \tx@Ellipse
  3701.       closepath}%
  3702.     \def\pst@linetype{2}%
  3703.   \end@ClosedObj}
  3704. %    \end{macrocode}
  3705. % \end{macro}
  3706. % \section{Repetition}
  3707. % \begin{macro}{\multirput}
  3708. %    \begin{macrocode}
  3709. \def\multirput{%
  3710.   \begingroup\pst@getref{\pst@getrputrot\multirput@i}}
  3711. \def\multirput@i(#1){\@ifnextchar(%
  3712.   {\multirput@ii(#1)}{\multirput@ii(0,0)(#1)}}
  3713. \def\multirput@ii(#1,#2)(#3,#4)#5{%
  3714.   \pst@makebox{\multirput@iii(#1,#2)(#3,#4){#5}}}
  3715. \def\multirput@iii(#1,#2)(#3,#4)#5{%
  3716.   \pst@makesmall\pst@hbox
  3717.   \ifx\pst@rot\@empty\else\pst@rotate\pst@hbox\fi
  3718.   \pssetxlength\pst@dima{#1}\pssetylength\pst@dimb{#2}
  3719.   \pssetxlength\pst@dimc{#3}\pssetylength\pst@dimd{#4}
  3720.   \pst@cntg=#5\relax\pst@cnth=0\relax
  3721.   \leavevmode
  3722.   \loop\ifnum\pst@cntg>\pst@cnth
  3723.     \vbox to \z@{\vss\hbox to \z@{%
  3724.       \kern\pst@dima\copy\pst@hbox\hss}\vskip\pst@dimb}%
  3725.     \advance\pst@dima by\pst@dimc
  3726.     \advance\pst@dimb by\pst@dimd
  3727.     \advance\pst@cnth by 1
  3728.   \repeat
  3729.   \endgroup\ignorespaces}
  3730. %    \end{macrocode}
  3731. % \end{macro}
  3732. % \begin{macro}{\multips}
  3733. %    \begin{macrocode}
  3734. \def\multips{\begingroup\pst@getrputrot\multips@i}
  3735. \def\multips@i(#1){\@ifnextchar({\@multips@ii(#1)}{\@multips@ii(0,0)(#1)}}
  3736. \def\@multips@ii(#1)(#2)#3#4{%
  3737.     \pst@getcoor{#1}\pst@tempa
  3738.     \pst@@getcoor{#2}%
  3739.     \pst@cnta=#3\relax
  3740.     \addto@pscode{%
  3741.       \pst@tempa T \the\pst@cnta\space \pslbrace
  3742.       gsave \ifx\pst@rot\@empty\else\pst@rot rotate \fi }%
  3743.     \hbox to\z@{%
  3744.       \def\init@pscode{%
  3745.         \addto@pscode{%
  3746.           gsave
  3747.           \pst@number\pslinewidth SLW
  3748.           \pst@usecolor\pslinecolor}}%
  3749.       \def\use@pscode{\addto@pscode{grestore}}%
  3750.       \def\psclip##1{\pst@misplaced\psclip}%
  3751.       \def\nc@object##1##2##3##4{\pst@misplaced{node connection}}%
  3752.       #4}%
  3753.     \addto@pscode{grestore \pst@coor T \psrbrace repeat}%
  3754.     \leavevmode
  3755.     \use@pscode
  3756.   \endgroup
  3757.   \ignorespaces}
  3758. %    \end{macrocode}
  3759. % \end{macro}
  3760. % \section{Scaling\label{Scaling}}
  3761. % \begin{macro}{\scalebox}
  3762. %    \begin{macrocode}
  3763. \def\scalebox#1{%
  3764.   \begingroup
  3765.     \pst@getscale{#1}\pst@tempa
  3766.     \pst@makebox{\@scalebox}}
  3767. \def\@scalebox{%
  3768.     \leavevmode
  3769.     \ifx\pst@tempa\@empty
  3770.       \box\pst@hbox
  3771.     \else
  3772.       \hbox{%
  3773.         \ht\pst@hbox=\pst@temph\ht\pst@hbox%
  3774.         \dp\pst@hbox=\pst@temph\dp\pst@hbox%
  3775.         \pst@dima=\pst@tempg\wd\pst@hbox%
  3776.         \ifdim\pst@dima<\z@\kern-\pst@dima\fi
  3777.         \pst@Verb{CP CP T \pst@tempa \tx@NET}%
  3778.         \hbox to \z@{\box\pst@hbox\hss}%
  3779.         \pst@Verb{%
  3780.           CP CP T
  3781.           1 \pst@tempg\space div 1 \pst@temph\space div scale
  3782.           \tx@NET}%
  3783.         \ifdim\pst@dima>\z@\kern\pst@dima\fi}%
  3784.     \fi
  3785.   \endgroup}
  3786. \pslongbox{Scalebox}{\scalebox}
  3787. %    \end{macrocode}
  3788. % \end{macro}
  3789. % \begin{macro}{\scaleboxto}
  3790. %    \begin{macrocode}
  3791. \def\scaleboxto(#1,#2){%
  3792.   \begingroup
  3793.     \pssetlength\pst@dima{#1}%
  3794.     \pssetlength\pst@dimb{#2}%
  3795.     \pst@makebox{\@scaleboxto\@scalebox}}
  3796. \def\@scaleboxto{%
  3797.     \ifdim\pst@dima=\z@\else
  3798.       \pst@divide{\pst@dima}{\wd\pst@hbox}\pst@tempg
  3799.     \fi
  3800.     \ifdim\pst@dimb=\z@
  3801.       \let\pst@temph\pst@tempg
  3802.     \else
  3803.       \pst@dimc=\ht\pst@hbox\advance\pst@dimc\dp\pst@hbox
  3804.       \pst@divide{\pst@dimb}{\pst@dimc}\pst@temph
  3805.       \ifdim\pst@dima=\z@\let\pst@tempg\pst@temph\fi
  3806.     \fi
  3807.     \edef\pst@tempa{\pst@tempg\space\pst@temph\space scale }%
  3808.     \ifdim\pst@dima=\z@
  3809.       \ifdim\pst@dimb=\z@
  3810.         \@pstrickserr{%
  3811.           \string\scaleboxto\space dimensions cannot both be zero}\@ehpa
  3812.         \def\pst@tempa{}%
  3813.     \fi\fi}
  3814. \pslongbox{Scaleboxto}{\scaleboxto}
  3815. %    \end{macrocode}
  3816. % \end{macro}
  3817. % \section{Rotation: The simple version\label{Rotation:simple}}
  3818. % \begin{macro}{\tx@Rot}
  3819. %    \begin{macrocode}
  3820. \pst@def{Rot}<\pstrotate>
  3821. %    \end{macrocode}
  3822. % \end{macro}
  3823. % \begin{macro}{\rotateleft,\rotateright,\rotatedown}
  3824. % These are pretty standard, except that they do not use "gsave" and
  3825. % "grestore".
  3826. %    \begin{macrocode}
  3827. \def\rotateleft{\pst@makebox{\@rotateleft\pst@hbox}}
  3828. \def\@rotateleft#1{%
  3829.   \leavevmode\hbox{\hskip\ht#1\hskip\dp#1\vbox{\vskip\wd#1%
  3830.   \pst@Verb{90 \tx@Rot}
  3831.   \vbox to \z@{\vss\hbox to \z@{\box#1\hss}\vskip\z@}%
  3832.   \pst@Verb{-90 \tx@Rot}}}}
  3833. \def\rotateright{\pst@makebox{\@rotateright\pst@hbox}}
  3834. \def\@rotateright#1{%
  3835.   \hbox{\hskip\ht#1\hskip\dp#1\vbox{\vskip\wd#1%
  3836.   \pst@Verb{-90 \tx@Rot}
  3837.   \vbox to \z@{\hbox to \z@{\hss\box#1}\vss}%
  3838.   \pst@Verb{90 \tx@Rot}}}}
  3839. \def\rotatedown{\pst@makebox{\@rotatedown\pst@hbox}}
  3840. \def\@rotatedown#1{%
  3841.   \hbox{\hskip\wd#1\vbox{\vskip\ht#1\vskip\dp#1%
  3842.   \pst@Verb{180 \tx@Rot}%
  3843.   \vbox to \z@{\hbox to \z@{\box#1\hss}\vss}%
  3844.   \pst@Verb{-180 \tx@Rot}}}}
  3845. \pslongbox{Rotateleft}{\rotateleft}
  3846. \pslongbox{Rotateright}{\rotateright}
  3847. \pslongbox{Rotatedown}{\rotatedown}
  3848. %    \end{macrocode}
  3849. % \end{macro}
  3850. % \section{{\tt\Backslash rput} and company}
  3851. % \n\rput\ and similar commands are divided into fours steps:
  3852. % \begin{enumerate}
  3853. %   \item The four arguments are collected:
  3854. %     \begin{enumerate}
  3855. % \item The reference point argument is stored in \n\refpoint@x\ and
  3856. % \n\refpoint@y.
  3857. %       \item The rotation angle is store in \n\pst@rot.
  3858. % \item The translation coordinate is passed to the command that is returned
  3859. % to after the box is made.
  3860. %       \item The RH-box is assigned to the register \n\pst@hbox.
  3861. %     \end{enumerate}
  3862. % \item The box is made zero-dimension and positioned at the reference point
  3863. % by \n\pst@makesmall.
  3864. %   \item The box is rotated by \n\pst@rotate.
  3865. %   \item The box is translated by \n\psput@.
  3866. % \end{enumerate}
  3867. % \subsection{Reference point}
  3868. % \begin{macro}{\pst@getref}
  3869. %    \begin{macrocode}
  3870. \def\pst@getref#1{%
  3871.   \@ifnextchar[%
  3872.     {\def\refpoint@x{.5}\def\refpoint@y{.5}\pst@@getref{#1}}%
  3873.     {\let\refpoint@x\relax#1}}
  3874. \def\pst@@getref#1[#2]{%
  3875.   \pst@expandafter\pst@@@getref{#2}\@empty,,\@nil#1}
  3876. \def\pst@@@getref#1#2,#3,#4\@nil{%
  3877.   \ifx\@empty#3\@empty
  3878.     \@nameuse{getref@#1}\@nameuse{getref@#2}%
  3879.   \else
  3880.     \pst@checknum{#1#2}\refpoint@x
  3881.     \pst@checknum{#3}\refpoint@y
  3882.   \fi}
  3883. \def\getref@t{\def\refpoint@y{1}}
  3884. \def\getref@b{\def\refpoint@y{0}}
  3885. \def\getref@B{\let\refpoint@y\relax}
  3886. \def\getref@l{\def\refpoint@x{0}}
  3887. \def\getref@r{\def\refpoint@x{1}}
  3888. %    \end{macrocode}
  3889. % \end{macro}
  3890. % \begin{macro}{\pst@makesmall}
  3891. %    \begin{macrocode}
  3892. \def\pst@makesmall#1{%
  3893.   \ifx\refpoint@x\relax
  3894.     \setbox#1=\hbox to\z@{\hss\vbox to \z@{\vss\box#1\vss}\hss}%
  3895.   \else
  3896.     \pst@@makesmall{#1}%
  3897.   \fi}
  3898. \def\pst@@makesmall#1{%
  3899.   \pst@dimh=\refpoint@x\wd#1%
  3900.   \ifx\refpoint@y\relax
  3901.     \pst@dimg=\dp#1%
  3902.   \else
  3903.     \pst@dimg=\refpoint@y\ht#1%
  3904.     \advance\pst@dimg\refpoint@y\dp#1%
  3905.   \fi
  3906.   \setbox#1=\hbox to\z@{%
  3907.     \hskip-\pst@dimh\vbox to\z@{\vss\box#1\vskip-\pst@dimg}\hss}}
  3908. %    \end{macrocode}
  3909. % \end{macro}
  3910. % \subsection{Rotation}
  3911. % \begin{macro}{\pst@getrputrot}
  3912. %    \begin{macrocode}
  3913. \def\pst@getrputrot#1{%
  3914.   \@ifnextchar(%
  3915.     {\def\pst@rot{}#1}%
  3916.     {\pst@getrot{\@ifnextchar({#1}{#1(0,0)}}}}
  3917. %    \end{macrocode}
  3918. % \end{macro}
  3919. % \begin{macro}{\pst@getrot}
  3920. %    \begin{macrocode}
  3921. \def\pst@getrot#1#2{%
  3922.   \pst@expandafter{\@ifnextchar*{\pst@@@getrot}{\pst@@getrot}}{#2}\@nil
  3923.   \ifx\pst@rotlist\@empty\else
  3924.     \edef\pst@rotlist{\pst@rotlist \pst@rot add }%
  3925.   \fi
  3926.   #1}
  3927. \def\pst@@getrot#1\@nil{%
  3928.   \def\next##1@#1=##2@##3\@nil{%
  3929.     \ifx\relax##2%
  3930.       \pst@getangle{#1}\pst@rot
  3931.     \else
  3932.       \def\pst@rot{##2}%
  3933.     \fi}%
  3934.   \expandafter\next\pst@rottable @#1=\relax @\@nil}
  3935. \def\pst@@@getrot#1#2\@nil{%
  3936.   \pst@@getrot#2\@nil
  3937.   \edef\pst@rot{\pst@rotlist neg \ifx\pst@rot\@empty\else\pst@rot add \fi}}%
  3938. \def\pst@rotlist{0 }
  3939. \def\pst@rot{}
  3940. %    \end{macrocode}
  3941. % \end{macro}
  3942. % \begin{macro}{\pst@rottable}
  3943. % The trailing spaces must be included, except when empty.
  3944. %    \begin{macrocode}
  3945. \def\pst@rottable{%
  3946.   @0=%
  3947.   @U=%
  3948.   @L=90 %
  3949.   @D=180 %
  3950.   @R=-90 %
  3951.   @N=\pst@rotlist neg %
  3952.   @W=\pst@rotlist neg 90 add %
  3953.   @S=\pst@rotlist neg 180 add %
  3954.   @E=\pst@rotlist neg 90 sub }
  3955. %    \end{macrocode}
  3956. % \end{macro}
  3957. % \begin{macro}{\pst@rotate}
  3958. % The last argument should be the register for a zero-dimensional box that is
  3959. % to be rotated. By first putting the box in a zero-dimension box centered at
  3960. % the reference point of the original box, we do not have to use "gsave" and
  3961. % "grestore".
  3962. %    \begin{macrocode}
  3963. \def\pst@rotate#1{%
  3964.   \setbox#1=\hbox{%
  3965.     \pst@Verb{\pst@rot \tx@Rot}%
  3966.     \box#1%
  3967.     \pst@Verb{\pst@rot neg \tx@Rot}}}
  3968. %    \end{macrocode}
  3969. % \end{macro}
  3970. % \subsection{Translation}
  3971. % \begin{macro}{\psput@cartesian,\psput@special}
  3972. % \n\psput@\ is defined by the \n\NormalCoor\ and \n\SpecialCoor\ commands to
  3973. % invoke either "\psput@cartesian" or "\psput@special".
  3974. % "\psput@cartesian" is for Cartesian coordinates only. \TeX\ does the
  3975. % translation.
  3976. % "\psput@special" works for any coordinates. PostScript does the translation.
  3977. % "/lmtrx" is used to store a stack of transformation for nested translations.
  3978. %    \begin{macrocode}
  3979. \def\psput@cartesian#1{%
  3980.   \hbox to \z@{\kern\pst@dimg{\vbox to \z@{\vss\box#1\vskip\pst@dimh}\hss}}}
  3981. \def\psput@special#1{%
  3982.   \hbox{%
  3983.     \pst@Verb{{ \pst@coor } \tx@PutCoor \tx@PutBegin}%
  3984.     \box#1%
  3985.     \pst@Verb{\tx@PutEnd}}}
  3986. \pst@def{PutCoor}<%
  3987.   gsave
  3988.     CP T
  3989.     CM
  3990.     \tx@STV
  3991.     exch exec
  3992.     moveto
  3993.     setmatrix
  3994.     CP
  3995.   grestore>
  3996. \pst@def{PutBegin}<%
  3997.   /lmtrx [ tx@Dict /lmtrx known { lmtrx aload pop } if CM ] def
  3998.   CP 4 2 roll T moveto>
  3999. \pst@def{PutEnd}<CP /lmtrx [ lmtrx aload pop setmatrix ] def moveto>
  4000. %    \end{macrocode}
  4001. % \end{macro}
  4002. % \subsection{The real thing}
  4003. % \begin{macro}{\begin@psput,\end@psput}
  4004. %    \begin{macrocode}
  4005. \def\begin@psput#1{\begingroup\pst@killglue\leavevmode\pst@ifstar{#1}}%
  4006. \def\end@psput#1(#2){%
  4007.   \pst@makebox{%
  4008.     \if@star
  4009.       \setbox\pst@hbox\hbox{\psframebox*[boxsep=false]{\unhbox\pst@hbox}}%
  4010.     \fi
  4011.     #1(#2)%
  4012.     \endgroup
  4013.     \ignorespaces}}
  4014. %    \end{macrocode}
  4015. % \end{macro}
  4016. % \begin{macro}{\rput}
  4017. %    \begin{macrocode}
  4018. \def\rput{\begin@psput{\pst@getref{\pst@getrputrot{\end@psput\rput@i}}}}
  4019. \def\rput@i(#1){%
  4020.     \pst@makesmall\pst@hbox
  4021.     \ifx\pst@rot\@empty\else\pst@rotate\pst@hbox\fi
  4022.     \psput@{#1}\pst@hbox}
  4023. %    \end{macrocode}
  4024. % \end{macro}
  4025. % \begin{macro}{\cput}
  4026. % The first argument of "\cput@iii" is a hook used by node commands.
  4027. %    \begin{macrocode}
  4028. \def\cput{\def\pst@par{}\pst@object{cput}}
  4029. \def\cput@i{\begingroup\pst@killglue\leavevmode\pst@getrputrot\cput@ii}
  4030. \def\cput@ii(#1){\pst@makebox{\cput@iii{}(#1)}}
  4031. \def\cput@iii#1(#2){%
  4032.     \setbox\pst@hbox=\hbox{\psboxsepfalse\pscirclebox@ii{#1}}%
  4033.     \let\refpoint@x\relax
  4034.     \rput@i(#2)%
  4035.   \endgroup
  4036.   \ignorespaces}
  4037. %    \end{macrocode}
  4038. % \end{macro}
  4039. % \section{{\tt\Backslash uput} and company}
  4040. % The difference between "\uput" and \n\rput\ is that "\rput"'s reference
  4041. % point is replaced by labelsep and reference angle arguments.
  4042. % \begin{macro}{\psset@labelsep,\pslabelsep}
  4043. %    \begin{macrocode}
  4044. \newdimen\pslabelsep
  4045. \def\psset@labelsep#1{\pssetlength\pslabelsep{#1}}
  4046. \psset@labelsep{5pt}
  4047. %    \end{macrocode}
  4048. % \end{macro}
  4049. % \begin{macro}{\pst@getrefangle}
  4050. %    \begin{macrocode}
  4051. \def\pst@getrefangle#1\@nil{%
  4052.   \def\next##1@#1=##2"##3@##4\@nil{%
  4053.     \ifx\relax##2%
  4054.       \pst@getangle{#1}\pst@refangle
  4055.       \def\pst@uputref{}%
  4056.     \else
  4057.       \edef\pst@refangle{##2}%
  4058.       \edef\pst@uputref{##3}%
  4059.     \fi}%
  4060.   \expandafter\next\pst@refangletable @#1=\relax"@\@nil}
  4061. %    \end{macrocode}
  4062. % \end{macro}
  4063. % \begin{macro}{\pst@refangletable}
  4064. %    \begin{macrocode}
  4065. \def\pst@refangletable{%
  4066.   @r=0"20%
  4067.   @u=90"02%
  4068.   @l=180"10%
  4069.   @d=-90"01%
  4070.   @ur=45"22%
  4071.   @ul=135"12%
  4072.   @dr=-135"21%
  4073.   @dl=-45"11}
  4074. %    \end{macrocode}
  4075. % \end{macro}
  4076. % \begin{macro}{\uput}
  4077. %    \begin{macrocode}
  4078. \def\uput{\begin@psput{\@ifnextchar[{\uput@ii}{\uput@i}}}
  4079. \def\uput@i#1{\pssetlength\pslabelsep{#1}\uput@ii}
  4080. \def\uput@ii[#1]{%
  4081.   \pst@expandafter\pst@getrefangle{#1}\@nil
  4082.   \pst@getrputrot{\end@psput\uput@iii}}
  4083. \def\uput@iii(#1){%
  4084.     \ifx\pst@uputref\@empty
  4085.       \uput@iv\tx@UUput
  4086.     \else
  4087.       \ifx\pst@rot\@empty
  4088.         \expandafter\uput@v\pst@uputref
  4089.       \else
  4090.         \uput@iv\tx@UUput
  4091.       \fi
  4092.     \fi
  4093.     \psput@{#1}\pst@hbox}
  4094. \def\uput@iv#1{%
  4095.   \edef\pst@coor{%
  4096.     \pst@number\pslabelsep
  4097.     \pst@number{\wd\pst@hbox}%
  4098.     \pst@number{\ht\pst@hbox}%
  4099.     \pst@number{\dp\pst@hbox}%
  4100.     \pst@refangle\space \ifx\pst@rot\@empty\else\pst@rot\space sub \fi
  4101.     \tx@Uput #1}%
  4102.   \setbox\pst@hbox=\hbox to\z@{\hss\vbox to\z@{\vss\box\pst@hbox\vss}\hss}%
  4103.   \setbox\pst@hbox=\psput@special\pst@hbox
  4104.   \ifx\pst@rot\@empty\else\pst@rotate\pst@hbox\fi}
  4105. \def\uput@v#1#2{%
  4106.   \ifnum#1>\z@\ifnum#2>\z@\pslabelsep=.707\pslabelsep\fi\fi
  4107.   \setbox\pst@hbox=\vbox to\z@{%
  4108.     \ifnum#2=1 \vskip\pslabelsep\else\vss\fi
  4109.     \hbox to\z@{%
  4110.       \ifnum#1=2 \hskip\pslabelsep\else\hss\fi
  4111.       \box\pst@hbox
  4112.       \ifnum#1=1 \hskip\pslabelsep\else\hss\fi}%
  4113.     \ifnum#2=2 \vskip\pslabelsep\else\vss\fi}}
  4114. %    \end{macrocode}
  4115. % \end{macro}
  4116. % \begin{macro}{\tx@Uput}
  4117. % I forget how this works, but it does.
  4118. %    \begin{macrocode}
  4119. \pst@def{Uput}<%
  4120.   /a ED
  4121.   add 2 div /h ED
  4122.   2 div /w ED
  4123.   /s a sin def
  4124.   /c a cos def
  4125.   s abs c abs 2 copy gt
  4126.   dup /q ED
  4127.   { pop } { exch pop } ifelse
  4128.   def
  4129.   /w1 c b div w mul def
  4130.   /h1 s b div h mul def
  4131.   { w1 abs w sub dup c mul abs }
  4132.   { h1 abs h sub dup s mul abs }
  4133.   ifelse>
  4134. \pst@def{UUput}<%
  4135.   /z ED
  4136.   abs /y ED
  4137.   /x ED
  4138.   { x s div c mul abs y gt }
  4139.   { x c div s mul abs y gt }
  4140.   ifelse
  4141.   { x x mul y y mul sub z z mul add sqrt z add }
  4142.   { q { x s div } { x c div } ifelse abs }
  4143.   ifelse
  4144.   a \tx@PtoC h1 add exch w1 add exch>
  4145. %    \end{macrocode}
  4146. % \end{macro}
  4147. % \begin{macro}{\pst@getlabelsep,\Rput}
  4148. % "\Rput" is an obsolete version of "\uput".
  4149. %    \begin{macrocode}
  4150. \def\pst@getlabelsep#1{%
  4151.   \@ifnextchar[%
  4152.     {\def\refpoint@x{.5}\def\refpoint@y{.5}\pst@@getref{#1}}%
  4153.     {\pst@@getlabelsep{#1}}}
  4154. \def\pst@@getlabelsep#1#2{\pssetlength\pslabelsep{#2}\pst@getref{#1}}
  4155. \def\Rput{%
  4156.   \begin@psput{\pst@getlabelsep{\pst@getrputrot{\end@psput{\Rput@i\rput@i}}}}}
  4157. \def\Rput@i{%
  4158.   \pst@dimg=\dp\pst@hbox
  4159.   \advance\pst@dimg\pslabelsep
  4160.   \dp\pst@hbox=\pst@dimg
  4161.   \pst@dimg=\ht\pst@hbox
  4162.   \advance\pst@dimg\pslabelsep
  4163.   \ht\pst@hbox=\pst@dimg
  4164.   \setbox\pst@hbox\hbox{\kern\pslabelsep\box\pst@hbox\kern\pslabelsep}}%
  4165. %    \end{macrocode}
  4166. % \end{macro}
  4167. % \section{Pictures\label{Pictures}}
  4168. % \begin{macro}{\pspicture}
  4169. %    \begin{macrocode}
  4170. \def\pspicture{\begingroup\pst@ifstar\pst@picture}
  4171. \def\pst@picture{%
  4172.   \@ifnextchar[{\pst@@picture}{\pst@@picture[0]}}
  4173. \def\pst@@picture[#1]#2(#3,#4){%
  4174.  \@ifnextchar({\pst@@@picture[#1](#3,#4)}%
  4175.    {\pst@@@picture[#1](0,0)(#3,#4)}}
  4176. \def\pst@@@picture[#1](#2,#3)(#4,#5){%
  4177.   \pssetxlength\pst@dima{#2}\pssetylength\pst@dimb{#3}%
  4178.   \pssetxlength\pst@dimc{#4}\pssetylength\pst@dimd{#5}%
  4179.   \def\pst@tempa{#1}%
  4180.   \setbox\pst@hbox=\hbox\bgroup
  4181.   \begingroup\KillGlue
  4182.   \@ifundefined{@latexerr}{}{\let\unitlength\psunit}%
  4183.   \edef\pic@coor{(#2,#3)(#2,#3)(#4,#5)}\ignorespaces}
  4184. \def\pic@coor{(0,0)(0,0)(10,10)}
  4185. \def\endpspicture{%
  4186.     \pst@killglue
  4187.     \endgroup
  4188.     \egroup
  4189.     \ifdim\wd\pst@hbox=\z@\else
  4190.       \@pstrickserr{Extraneous space in the pspicture environment}%
  4191.         {Type \space <return> \space to procede.}%
  4192.     \fi
  4193.     \ht\pst@hbox=\pst@dimd
  4194.     \dp\pst@hbox=-\pst@dimb
  4195.     \setbox\pst@hbox=\hbox{%
  4196.       \kern-\pst@dima
  4197.       \ifx\pst@tempa\@empty\else
  4198.         \advance\pst@dimd-\pst@dimb
  4199.         \pst@dimd=\pst@tempa\pst@dimd
  4200.         \advance\pst@dimd\pst@dimb
  4201.         \lower\pst@dimd
  4202.       \fi
  4203.       \box\pst@hbox
  4204.       \kern\pst@dimc}%
  4205.     \if@star\setbox\pst@hbox=\hbox{\clipbox@@\z@}\fi
  4206.     \leavevmode\box\pst@hbox
  4207.   \endgroup}
  4208. \@namedef{pspicture*}{\pspicture*}
  4209. \@namedef{endpspicture*}{\endpspicture}
  4210. %    \end{macrocode}
  4211. % \end{macro}
  4212. % \section{Overlays\label{Overlays}}
  4213. % Overlays work by translating invisible material. They take advantage of the
  4214. % fact that PostScript is running parallel to \TeX, and so we can redefine the
  4215. % value of some PostScript variables in order to get a different overlay
  4216. % printed each time we output a box containing overlay commands (even though
  4217. % the box has already been typeset by \TeX).
  4218. % \begin{macro}{BeginOverlay}
  4219. % "BeginOL" is a PostScript procedure, with syntax:
  4220. % \begin{LVerbatim}
  4221. %   (<string>) BeginOL
  4222. % \end{LVerbatim}
  4223. % If the string is not "(all)" and does not match "TheOL", then the output is
  4224. % made invisible by translating it over by the coffee pot (actually, by a
  4225. % distance "OLUnit"). Otherwise, it is made visible by translating it back to
  4226. % the page.
  4227. % Rather than translating the page, we could define a small clipping path off
  4228. % the page, but that would be more likely to be messed up by someone's
  4229. % "initclip" (e.g., by PSTricks' "initclip"!).
  4230. %    \begin{macrocode}
  4231. \pst@def{BeginOL}<%
  4232.   dup (all) eq exch TheOL eq or
  4233.   { IfVisible not
  4234.     { CP OLUnit T moveto
  4235.       /IfVisible true def }
  4236.     if }
  4237.   { IfVisible
  4238.     { CP OLUnit \tx@NET moveto
  4239.       /IfVisible false def }
  4240.     if }
  4241.   ifelse>
  4242. %    \end{macrocode}
  4243. % \end{macro}
  4244. % \begin{macro}{InitOL}
  4245. % This figures out how far in the current units used by the driver is 50
  4246. % inches up and to the right. This works even though drivers use unusual
  4247. % coordinate systems (even "dvips"). This macro also defines "BOL" to be
  4248. % "BeginOL" and sets the default value of "IfVisible".
  4249. %    \begin{macrocode}
  4250. \pst@dimg=40in
  4251. \edef\pst@OLunit{\pst@number\pst@dimg}
  4252. \pst@def{InitOL}<%
  4253.   /OLUnit [ gsave CM \tx@STV \pst@OLunit
  4254.     dup moveto setmatrix CP grestore ] cvx def
  4255.   /BOL { \tx@BeginOL } def /IfVisible true def>
  4256. %    \end{macrocode}
  4257. % \end{macro}
  4258. % \begin{macro}{\pst@initoverlay}
  4259. % This defines "TheOL" to be "#1". It must be inserted just before printing
  4260. % overlay "#1".
  4261. %    \begin{macrocode}
  4262. \def\pst@initoverlay#1{\pst@Verb{\tx@InitOL /TheOL (#1) def}}
  4263. %    \end{macrocode}
  4264. % \end{macro}
  4265. % \begin{macro}{\pst@overlay,\pst@endoverlay}
  4266. % "\pst@overlay" just calls "BeginOverlay".
  4267. %    \begin{macrocode}
  4268. \def\pst@overlay#1{%
  4269.   \edef\curr@overlay{#1}%
  4270.   \pst@Verb{(#1) BOL}%
  4271.   \aftergroup\pst@endoverlay}
  4272. \def\pst@endoverlay{%
  4273.   \pst@Verb{(\curr@overlay) BOL}}
  4274. \def\curr@overlay{all}
  4275. %    \end{macrocode}
  4276. % \end{macro}
  4277. % \begin{macro}{\overlaybox,\endoverlaybox,\putoverlaybox}
  4278. % "\pst@initoverlay", "\pst@overlay", and "\pst@endoverlay" are the overlays
  4279. % primitives. An interface must be set up that guarantees that "\pst@overlay"
  4280. % and "\pst@endoverlay" are only used inside a box, and that
  4281. % "\pst@initoverlay" is inserted each type the box is printed. Here is one
  4282. % such interface (see "seminar.sty" for an interface for slides). The extra
  4283. % "\begingroup" and "\endgroup" assure that each "\pst@endoverlay" is executed
  4284. % within the box.
  4285. %    \begin{macrocode}
  4286. \newbox\theoverlaybox
  4287. \def\overlaybox{%
  4288.   \setbox\theoverlaybox=\hbox\bgroup
  4289.     \begingroup
  4290.     \let\psoverlay\pst@overlay
  4291.     \def\overlaybox{%
  4292.       \@pstrickserr{Overlays cannot be nested}\@eha}%
  4293.     \def\putoverlaybox{%
  4294.       \@pstrickserr{You must end the overlay box
  4295.       before using \string\putoverlaybox}}%
  4296.     \psoverlay{main}}
  4297. \def\endoverlaybox{\endgroup\egroup}
  4298. \def\putoverlaybox#1{%
  4299.   \hbox{\pst@initoverlay{#1}\copy\theoverlaybox}}
  4300. \def\psoverlay{\@pstrickserr{\string\psoverlay\space
  4301.   can only be used after \string\overlaybox}}
  4302. %    \end{macrocode}
  4303. % \end{macro}
  4304. % \section{Configuration file -- revisited\label{Config:revisited}}
  4305. %    \begin{macrocode}
  4306. \ifx\pstcustomize\relax \input pstricks.con \fi
  4307. %    \end{macrocode}
  4308. %    \begin{macrocode}
  4309. \pst@ATH<end>
  4310. \catcode`\@=\PstAtCode\relax
  4311. \endinput
  4312. %    \end{macrocode}
  4313. % \endinput
  4314. %% END: pstricks.doc
  4315.